diff --git a/.gitignore b/.gitignore index 8cb2b59b..3fd55275 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ qsyn* !src/qsyn* !src/qsyn/qsyn* +# for work-in-progress things +wip/ + # vscode configuration files and folders .vscode diff --git a/src/convert/qcir_to_zxgraph.cpp b/src/convert/qcir_to_zxgraph.cpp index ab1087a7..fd4b396f 100644 --- a/src/convert/qcir_to_zxgraph.cpp +++ b/src/convert/qcir_to_zxgraph.cpp @@ -46,7 +46,7 @@ create_multi_control_backbone(ZXGraph& g, std::vector const& qubits, for (auto const& bitinfo : qubits) { auto qubit = bitinfo._qubit; ZXVertex* in = g.add_input(qubit); - ZXVertex* v = g.add_vertex(qubit, VertexType::z); + ZXVertex* v = g.add_vertex(VertexType::z, dvlab::Phase{}, static_cast(qubit)); ZXVertex* out = g.add_output(qubit); if (ax == RotationAxis::z || !bitinfo._isTarget) { g.add_edge(in, v, EdgeType::simple); @@ -164,7 +164,7 @@ ZXGraph create_single_vertex_zx_form(QCirGate* gate, VertexType vt, dvlab::Phase auto qubit = gate->get_qubits()[0]._qubit; ZXVertex* in = g.add_input(qubit); - ZXVertex* v = g.add_vertex(qubit, vt, ph); + ZXVertex* v = g.add_vertex(vt, ph, static_cast(qubit)); ZXVertex* out = g.add_output(qubit); g.add_edge(in, v, EdgeType::simple); g.add_edge(v, out, EdgeType::simple); @@ -186,8 +186,8 @@ ZXGraph create_cx_zx_form(QCirGate* gate) { ZXVertex* in_ctrl = g.add_input(ctrl_qubit); ZXVertex* in_targ = g.add_input(targ_qubit); - ZXVertex* ctrl = g.add_vertex(ctrl_qubit, VertexType::z, dvlab::Phase(0)); - ZXVertex* targ_x = g.add_vertex(targ_qubit, VertexType::x, dvlab::Phase(0)); + ZXVertex* ctrl = g.add_vertex(VertexType::z, dvlab::Phase(0), static_cast(ctrl_qubit)); + ZXVertex* targ_x = g.add_vertex(VertexType::x, dvlab::Phase(0), static_cast(targ_qubit)); ZXVertex* out_ctrl = g.add_output(ctrl_qubit); ZXVertex* out_targ = g.add_output(targ_qubit); g.add_edge(in_ctrl, ctrl, EdgeType::simple); @@ -212,7 +212,7 @@ ZXGraph create_ccx_zx_form(QCirGate* gate, size_t decomposition_mode) { auto targ_qubit = gate->get_qubits()[0]._isTarget ? gate->get_qubits()[0]._qubit : (gate->get_qubits()[1]._isTarget ? gate->get_qubits()[1]._qubit : gate->get_qubits()[2]._qubit); std::vector, QubitIdType>> vertices_info; std::vector, EdgeType>> adj_pair; - std::vector vertices_col; + std::vector vertices_col; std::vector vertices_list = {}; ZXVertex* in_ctrl_1 = nullptr; ZXVertex* in_ctrl_2 = nullptr; @@ -230,11 +230,8 @@ ZXGraph create_ccx_zx_form(QCirGate* gate, size_t decomposition_mode) { in_ctrl_2 = g.add_input(ctrl_qubit_2, 0); in_targ = g.add_input(targ_qubit, 0); for (size_t i = 0; i < vertices_info.size(); i++) { - vertices_list.emplace_back(g.add_vertex(vertices_info[i].second, vertices_info[i].first.first, vertices_info[i].first.second)); + vertices_list.emplace_back(g.add_vertex(vertices_info[i].first.first, vertices_info[i].first.second, static_cast(vertices_info[i].second), vertices_col[i])); }; - for (size_t i = 0; i < vertices_col.size(); i++) { - vertices_list[i]->set_col(vertices_col[i]); - } out_ctrl_1 = g.add_output(ctrl_qubit_1, 12); out_ctrl_2 = g.add_output(ctrl_qubit_2, 12); out_targ = g.add_output(targ_qubit, 12); @@ -254,11 +251,8 @@ ZXGraph create_ccx_zx_form(QCirGate* gate, size_t decomposition_mode) { in_ctrl_2 = g.add_input(ctrl_qubit_2, 0); in_targ = g.add_input(targ_qubit, 0); for (size_t i = 0; i < vertices_info.size(); i++) { - vertices_list.emplace_back(g.add_vertex(vertices_info[i].second, vertices_info[i].first.first, vertices_info[i].first.second)); + vertices_list.emplace_back(g.add_vertex(vertices_info[i].first.first, vertices_info[i].first.second, static_cast(vertices_info[i].second), vertices_col[i])); }; - for (size_t i = 0; i < vertices_col.size(); i++) { - vertices_list[i]->set_col(vertices_col[i]); - } out_ctrl_1 = g.add_output(ctrl_qubit_1, 12); out_ctrl_2 = g.add_output(ctrl_qubit_2, 12); out_targ = g.add_output(targ_qubit, 12); @@ -277,11 +271,8 @@ ZXGraph create_ccx_zx_form(QCirGate* gate, size_t decomposition_mode) { in_ctrl_2 = g.add_input(ctrl_qubit_2, 0); in_targ = g.add_input(targ_qubit, 0); for (size_t i = 0; i < vertices_info.size(); i++) { - vertices_list.emplace_back(g.add_vertex(vertices_info[i].second, vertices_info[i].first.first, vertices_info[i].first.second)); + vertices_list.emplace_back(g.add_vertex(vertices_info[i].first.first, vertices_info[i].first.second, static_cast(vertices_info[i].second), vertices_col[i])); }; - for (size_t i = 0; i < vertices_col.size(); i++) { - vertices_list[i]->set_col(vertices_col[i]); - } out_ctrl_1 = g.add_output(ctrl_qubit_1, 6); out_ctrl_2 = g.add_output(ctrl_qubit_2, 6); out_targ = g.add_output(targ_qubit, 6); @@ -301,14 +292,12 @@ ZXGraph create_ccx_zx_form(QCirGate* gate, size_t decomposition_mode) { in_ctrl_2 = g.add_input(ctrl_qubit_2, 0); in_targ = g.add_input(targ_qubit, 0); for (size_t i = 0; i < vertices_info.size(); i++) { - vertices_list.emplace_back(g.add_vertex(vertices_info[i].second, vertices_info[i].first.first, vertices_info[i].first.second)); + vertices_list.emplace_back(g.add_vertex(vertices_info[i].first.first, vertices_info[i].first.second, static_cast(vertices_info[i].second), vertices_col[i])); }; - for (size_t i = 0; i < vertices_col.size(); i++) { - vertices_list[i]->set_col(vertices_col[i]); - } out_ctrl_1 = g.add_output(ctrl_qubit_1, 12); out_ctrl_2 = g.add_output(ctrl_qubit_2, 12); out_targ = g.add_output(targ_qubit, 12); + g.add_edge(in_ctrl_1, vertices_list[16], EdgeType::simple); g.add_edge(in_ctrl_2, vertices_list[10], EdgeType::simple); g.add_edge(in_targ, vertices_list[0], EdgeType::hadamard); @@ -349,8 +338,8 @@ ZXGraph create_cz_zx_form(QCirGate* gate) { ZXVertex* in_ctrl = g.add_input(ctrl_qubit); ZXVertex* in_targ = g.add_input(targ_qubit); - ZXVertex* ctrl = g.add_vertex(ctrl_qubit, VertexType::z, dvlab::Phase(0)); - ZXVertex* targ_z = g.add_vertex(targ_qubit, VertexType::z, dvlab::Phase(0)); + ZXVertex* ctrl = g.add_vertex(VertexType::z, dvlab::Phase(0), static_cast(ctrl_qubit)); + ZXVertex* targ_z = g.add_vertex(VertexType::z, dvlab::Phase(0), static_cast(targ_qubit)); ZXVertex* out_ctrl = g.add_output(ctrl_qubit); ZXVertex* out_targ = g.add_output(targ_qubit); g.add_edge(in_ctrl, ctrl, EdgeType::simple); @@ -372,9 +361,9 @@ ZXGraph create_ry_zx_form(QCirGate* gate, dvlab::Phase ph) { auto qubit = gate->get_qubits()[0]._qubit; ZXVertex* in = g.add_input(qubit); - ZXVertex* sdg = g.add_vertex(qubit, VertexType::z, dvlab::Phase(-1, 2)); - ZXVertex* rx = g.add_vertex(qubit, VertexType::x, ph); - ZXVertex* s = g.add_vertex(qubit, VertexType::z, dvlab::Phase(1, 2)); + ZXVertex* sdg = g.add_vertex(VertexType::z, dvlab::Phase(-1, 2), static_cast(qubit)); + ZXVertex* rx = g.add_vertex(VertexType::x, ph, static_cast(qubit)); + ZXVertex* s = g.add_vertex(VertexType::z, dvlab::Phase(1, 2), static_cast(qubit)); ZXVertex* out = g.add_output(qubit); g.add_edge(in, sdg, EdgeType::simple); g.add_edge(sdg, rx, EdgeType::simple); @@ -454,9 +443,8 @@ std::optional to_zxgraph(QCir const& qcir, size_t decomposition_mode) { ZXGraph g; spdlog::debug("Add boundaries"); for (size_t i = 0; i < qcir.get_qubits().size(); i++) { - ZXVertex* input = g.add_input(qcir.get_qubits()[i]->get_id()); + ZXVertex* input = g.add_input(qcir.get_qubits()[i]->get_id(), 0); ZXVertex* output = g.add_output(qcir.get_qubits()[i]->get_id()); - input->set_col(0); g.add_edge(input, output, EdgeType::simple); } @@ -468,7 +456,7 @@ std::optional to_zxgraph(QCir const& qcir, size_t decomposition_mode) { assert(tmp.has_value()); for (auto& v : tmp->get_vertices()) { - v->set_col(v->get_col() + static_cast(gate->get_time())); + v->set_col(v->get_col() + static_cast(gate->get_time())); } g.concatenate(*tmp); diff --git a/src/extractor/extract.cpp b/src/extractor/extract.cpp index 57f357a2..ef3f09e8 100644 --- a/src/extractor/extract.cpp +++ b/src/extractor/extract.cpp @@ -81,7 +81,7 @@ void Extractor::initialize(bool from_empty_qcir) { } print_frontier(spdlog::level::level_enum::trace); print_neighbors(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); } @@ -105,12 +105,12 @@ QCir* Extractor::extract() { spdlog::info("Finished Extracting!"); _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); if (PERMUTE_QUBITS) { permute_qubits(); _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); } return _logical_circuit; @@ -133,7 +133,7 @@ bool Extractor::extraction_loop(std::optional max_iter) { if (remove_gadget()) { spdlog::debug("Gadget(s) are removed."); print_frontier(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); continue; } @@ -156,7 +156,7 @@ bool Extractor::extraction_loop(std::optional max_iter) { print_frontier(spdlog::level::level_enum::trace); print_neighbors(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); if (max_iter.has_value()) (*max_iter)--; @@ -199,7 +199,7 @@ void Extractor::extract_singles() { _graph->remove_edge(s, t, EdgeType::hadamard); } _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); } /** @@ -245,7 +245,7 @@ bool Extractor::extract_czs(bool check) { prepend_series_gates(ops); } _logical_circuit->print_circuit_diagram(spdlog::level::level_enum::trace); - _graph->print_vertices_by_qubits(spdlog::level::level_enum::trace); + _graph->print_vertices_by_rows(spdlog::level::level_enum::trace); return true; } @@ -382,6 +382,7 @@ bool Extractor::remove_gadget(bool check) { } for (auto& [candidate, _] : _graph->get_neighbors(n)) { if (_frontier.contains(candidate)) { + auto const qubit = candidate->get_qubit(); _axels.erase(n); _frontier.erase(candidate); @@ -396,6 +397,8 @@ bool Extractor::remove_gadget(bool check) { PivotBoundaryRule().apply(*_graph, {{candidate, n}}); assert(target_boundary != nullptr); + auto new_frontier = _graph->get_first_neighbor(target_boundary).first; + new_frontier->set_qubit(qubit); _frontier.emplace(_graph->get_first_neighbor(target_boundary).first); // REVIEW - qubit_map removed_some_gadgets = true; diff --git a/src/zx/simplifier/rules/state_copy_rule.cpp b/src/zx/simplifier/rules/state_copy_rule.cpp index 4ea1fa6c..f524138d 100644 --- a/src/zx/simplifier/rules/state_copy_rule.cpp +++ b/src/zx/simplifier/rules/state_copy_rule.cpp @@ -67,7 +67,7 @@ void StateCopyRule::apply(ZXGraph& graph, std::vector const& matches) op.vertices_to_remove.emplace_back(a); for (auto neighbor : neighbors) { if (neighbor->get_type() == VertexType::boundary) { - ZXVertex* const new_v = graph.add_vertex(neighbor->get_qubit(), VertexType::z, npi->get_phase()); + ZXVertex* const new_v = graph.add_vertex(VertexType::z, npi->get_phase(), neighbor->get_row(), (neighbor->get_col() + a->get_col()) / 2); auto const is_simple_edge = graph.get_first_neighbor(neighbor).second == EdgeType::simple; op.edges_to_remove.emplace_back(std::make_pair(a, neighbor), graph.get_first_neighbor(neighbor).second); @@ -78,8 +78,6 @@ void StateCopyRule::apply(ZXGraph& graph, std::vector const& matches) // a to new op.edges_to_add.emplace_back(std::make_pair(a, new_v), EdgeType::hadamard); - new_v->set_col((neighbor->get_col() + a->get_col()) / 2); - } else { neighbor->set_phase(npi->get_phase() + neighbor->get_phase()); } diff --git a/src/zx/zx_cmd.cpp b/src/zx/zx_cmd.cpp index 724a6c27..7dc1616d 100644 --- a/src/zx/zx_cmd.cpp +++ b/src/zx/zx_cmd.cpp @@ -17,6 +17,7 @@ #include "util/data_structure_manager.hpp" #include "util/data_structure_manager_common_cmd.hpp" #include "zx/simplifier/simp_cmd.hpp" +#include "zx/zx_io.hpp" using namespace dvlab::argparse; using dvlab::CmdExecResult; @@ -183,9 +184,9 @@ Command zxgraph_print_cmd(ZXGraphMgr const& zxgraph_mgr) { mutex.add_argument("-e", "--edges") .action(store_true) .help("print the edges info of ZXGraph"); - mutex.add_argument("-q", "--qubits") + mutex.add_argument("-r", "--rows") .nargs(NArgsOption::zero_or_more) - .help("print the vertices of ZXGraph by their qubits"); + .help("print the vertices of ZXGraph row by row"); mutex.add_argument("-n", "--neighbors") .constraint(valid_zxvertex_id(zxgraph_mgr)) .help("print the neighbor info of ZXGraph"); @@ -217,9 +218,9 @@ Command zxgraph_print_cmd(ZXGraphMgr const& zxgraph_mgr) { zxgraph_mgr.get()->print_vertices(vids); } else if (parser.parsed("--edges")) { zxgraph_mgr.get()->print_edges(); - } else if (parser.parsed("--qubits")) { - auto qids = parser.get>("--qubits"); - zxgraph_mgr.get()->print_vertices_by_qubits(spdlog::level::level_enum::off, qids); + } else if (parser.parsed("--rows")) { + auto qids = parser.get>("--rows"); + zxgraph_mgr.get()->print_vertices_by_rows(spdlog::level::level_enum::off, qids); } else if (parser.parsed("--neighbors")) { auto v = zxgraph_mgr.get()->find_vertex_by_id(parser.get("--neighbors")); v->print_vertex(); @@ -246,10 +247,6 @@ Command zxgraph_draw_cmd(ZXGraphMgr const& zxgraph_mgr) { .constraint(path_writable) .constraint(allowed_extension({".pdf"})) .help("the output path. Supported extension: .pdf"); - - parser.add_argument("-cli") - .action(store_true) - .help("print to the terminal. Note that only horizontal wires will be printed"); }, [&](ArgumentParser const& parser) { if (!dvlab::utils::mgr_has_data(zxgraph_mgr)) return CmdExecResult::error; @@ -257,10 +254,6 @@ Command zxgraph_draw_cmd(ZXGraphMgr const& zxgraph_mgr) { zxgraph_mgr.get()->adjust_vertex_coordinates(); if (!zxgraph_mgr.get()->write_pdf(parser.get("filepath"))) return CmdExecResult::error; } - if (parser.parsed("-cli")) { - spdlog::warn("This feature is deprecated and will be removed in the future."); - zxgraph_mgr.get()->draw(); - } return CmdExecResult::done; }}; @@ -286,12 +279,12 @@ Command zxgraph_read_cmd(ZXGraphMgr& zxgraph_mgr) { .help("replace the current ZXGraph"); }, [&](ArgumentParser const& parser) { - auto filepath = parser.get("filepath"); - auto do_keep_id = parser.get("--keep-id"); - auto do_replace = parser.get("--replace"); + auto const filepath = parser.get("filepath"); + auto const do_keep_id = parser.get("--keep-id"); + auto const do_replace = parser.get("--replace"); - auto buffer_graph = std::make_unique(); - if (!buffer_graph->read_zx(filepath, do_keep_id)) { + auto const graph = from_zx(filepath, do_keep_id); + if (!graph) { return CmdExecResult::error; } @@ -302,9 +295,9 @@ Command zxgraph_read_cmd(ZXGraphMgr& zxgraph_mgr) { } else { spdlog::info("Original ZXGraph is replaced..."); } - zxgraph_mgr.set(std::move(buffer_graph)); + zxgraph_mgr.set(std::make_unique(std::move(graph.value()))); } else { - zxgraph_mgr.add(zxgraph_mgr.get_next_id(), std::move(buffer_graph)); + zxgraph_mgr.add(zxgraph_mgr.get_next_id(), std::make_unique(std::move(graph.value()))); } zxgraph_mgr.get()->set_filename(std::filesystem::path{filepath}.stem()); return CmdExecResult::done; @@ -410,35 +403,50 @@ Command zxgraph_vertex_add_cmd(ZXGraphMgr& zxgraph_mgr) { [](ArgumentParser& parser) { parser.description("add vertices to ZXGraph"); - parser.add_argument("vtype") - .constraint(choices_allow_prefix({"input", "output", "zspider", "xspider", "hbox"})) - .help("the type of the vertex. Choices: `input`, `output`, `zspider`, `xspider`, `hbox`"); + auto subparsers = parser.add_subparsers().required(true); + + auto i_parser = subparsers.add_parser("input") + .description("add input vertex to ZXGraph"); + auto o_parser = subparsers.add_parser("output") + .description("add output vertex to ZXGraph"); + auto z_parser = subparsers.add_parser("zspider") + .description("add Z-Spider vertex to ZXGraph"); + auto x_parser = subparsers.add_parser("xspider") + .description("add X-Spider vertex to ZXGraph"); + auto h_parser = subparsers.add_parser("hbox") + .description("add H-Box vertex to ZXGraph"); - parser.add_argument("qubit") + i_parser.add_argument("qubit") .nargs(NArgsOption::optional) - .help("the qubit ID of the vertex. If adding input or output vertices, this argument must be unique"); + .help("specify the unique qubit ID for input or output vertex. if not specified, a new qubit ID will be assigned"); - parser.add_argument("phase") + o_parser.add_argument("qubit") + .nargs(NArgsOption::optional) + .help("specify the unique qubit ID for input or output vertex. if not specified, a new qubit ID will be assigned"); + + z_parser.add_argument("phase") + .nargs(NArgsOption::optional) + .help("the phase of the vertex. Default: 0"); + + x_parser.add_argument("phase") .nargs(NArgsOption::optional) .help("the phase of the vertex. Default: 0"); + + h_parser.add_argument("phase") + .nargs(NArgsOption::optional) + .help("the phase of the vertex. Default: pi"); }, [&](ArgumentParser const& parser) { if (!dvlab::utils::mgr_has_data(zxgraph_mgr)) return CmdExecResult::error; - auto const vtype_str = parser.get("vtype"); - if (dvlab::str::is_prefix_of(vtype_str, "input")) { - if (!parser.parsed("qubit")) { - spdlog::error("The qubit ID of the input vertex must be specified!!"); - return CmdExecResult::error; - } - auto const qid = parser.get("qubit"); + + if (parser.used_subparser("input")) { + auto const qid = parser.parsed("qubit") + ? parser.get("qubit") + : gsl::narrow(std::ranges::max(zxgraph_mgr.get()->get_input_list() | std::views::keys) + 1); if (zxgraph_mgr.get()->is_input_qubit(qid)) { spdlog::error("Input vertex for qubit {} already exists!!", qid); return CmdExecResult::error; } - if (parser.parsed("phase")) { - spdlog::error("Input vertex cannot have phase!!"); - return CmdExecResult::error; - } zxgraph_mgr.get()->add_input(qid); @@ -447,20 +455,14 @@ Command zxgraph_vertex_add_cmd(ZXGraphMgr& zxgraph_mgr) { return CmdExecResult::done; } - if (dvlab::str::is_prefix_of(vtype_str, "output")) { - if (!parser.parsed("qubit")) { - spdlog::error("The qubit ID of the output vertex must be specified!!"); - return CmdExecResult::error; - } - auto const qid = parser.get("qubit"); + if (parser.used_subparser("output")) { + auto const qid = parser.parsed("qubit") + ? parser.get("qubit") + : gsl::narrow(std::ranges::max(zxgraph_mgr.get()->get_output_list() | std::views::keys) + 1); if (zxgraph_mgr.get()->is_output_qubit(qid)) { spdlog::error("Error: output vertex for qubit {} already exists!!", qid); return CmdExecResult::error; } - if (parser.parsed("phase")) { - spdlog::error("Error: output vertex cannot have phase!!"); - return CmdExecResult::error; - } zxgraph_mgr.get()->add_output(qid); @@ -469,19 +471,21 @@ Command zxgraph_vertex_add_cmd(ZXGraphMgr& zxgraph_mgr) { return CmdExecResult::done; } - auto const vtype = str_to_vertex_type(vtype_str); + auto const vtype = std::invoke([&]() -> std::optional { + if (parser.used_subparser("zspider")) return VertexType::z; + if (parser.used_subparser("xspider")) return VertexType::x; + if (parser.used_subparser("hbox")) return VertexType::h_box; + return std::nullopt; + }); assert(vtype.has_value()); - auto qid = parser.parsed("qubit") - ? parser.get("qubit") - : 0; auto phase = parser.parsed("phase") ? parser.get("phase") : ((vtype == VertexType::h_box) ? Phase(1) : Phase(0)); - auto v = zxgraph_mgr.get()->add_vertex(qid, vtype.value(), phase); + auto v = zxgraph_mgr.get()->add_vertex(vtype.value(), phase); spdlog::info("Adding vertex {}...", v->get_id()); return CmdExecResult::done; diff --git a/src/zx/zx_def.hpp b/src/zx/zx_def.hpp index 6d3132b7..b0c70e52 100644 --- a/src/zx/zx_def.hpp +++ b/src/zx/zx_def.hpp @@ -93,20 +93,6 @@ struct ZXCutEqual { using ZXCutSet = dvlab::utils::ordered_hashset; -namespace detail { - -struct VertexInfo { - char type = 'Z'; - QubitIdType qubit = 0; - float column = 0.0f; - std::vector> neighbors; - Phase phase; -}; - -using StorageType = dvlab::utils::ordered_hashmap; - -} // namespace detail - //------------------------------------------------------------------------ // Define hashes //------------------------------------------------------------------------ diff --git a/src/zx/zx_file_parser.cpp b/src/zx/zx_file_parser.cpp deleted file mode 100644 index c5b2b37d..00000000 --- a/src/zx/zx_file_parser.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/**************************************************************************** - PackageName [ zx ] - Synopsis [ Define zxFileStructure member functions ] - Author [ Design Verification Lab ] - Copyright [ Copyright(c) 2023 DVLab, GIEE, NTU, Taiwan ] -****************************************************************************/ - -#include "./zx_file_parser.hpp" - -#include -#include - -#include - -#include "util/dvlab_string.hpp" -#include "util/phase.hpp" -#include "util/util.hpp" - -namespace qsyn { - -namespace zx { - -static constexpr std::string_view supported_vertex_type = "IOZXH"; -static constexpr std::string_view supported_edge_type = "SH"; - -/** - * @brief Parse the file - * - * @param filename - * @return true if the file is successfully parsed - * @return false if error happens - */ -bool ZXFileParser::parse(std::filesystem::path const& filename) { - _storage.clear(); - _taken_input_qubits.clear(); - _taken_output_qubits.clear(); - - std::ifstream zx_file(filename); - if (!zx_file.is_open()) { - spdlog::error("Cannot open the file \"{}\"!!", filename); - return false; - } - - return _parse_internal(zx_file); -} - -/** - * @brief Parse each line in the file - * - * @param f - * @return true if the file is successfully parsed - * @return false if the format of any lines are wrong - */ -bool ZXFileParser::_parse_internal(std::ifstream& f) { - // each line should be in the format of - // [()] [NeighborString...] [Phase phase] - _line_no = 1; - for (std::string line; getline(f, line); _line_no++) { - line = dvlab::str::trim_spaces(dvlab::str::trim_comments(line)); - if (line.empty()) continue; - - std::vector tokens; - if (!_tokenize(line, tokens)) return false; - - VertexInfo info; - - auto const type_and_id = _parse_type_and_id(tokens[0]); - if (!type_and_id.has_value()) return false; - - info.type = type_and_id.value().first; - auto id = type_and_id.value().second; - - if (info.type == 'I' || info.type == 'O') { - if (!_is_valid_tokens_for_boundary_vertex(tokens)) return false; - } - if (info.type == 'H') { - if (!_is_valid_tokens_for_h_box(tokens)) return false; - info.phase = Phase(1); - } - - if (!_parse_qubit(tokens[1], info.type, info.qubit)) return false; - if (!_parse_column(tokens[2], info.column)) return false; - - if (tokens.size() > 3) { - if (auto phase = Phase::from_string(tokens.back()); phase.has_value()) { - tokens.pop_back(); - info.phase = phase.value(); - } - - std::pair neighbor; - for (size_t i = 3; i < tokens.size(); ++i) { - if (!_parse_neighbors(tokens[i], neighbor)) return false; - info.neighbors.emplace_back(neighbor); - } - } - - _storage[id] = info; - } - - return true; -} - -/** - * @brief Tokenize the line - * - * @param line - * @param tokens - * @return true - * @return false - */ -bool ZXFileParser::_tokenize(std::string const& line, std::vector& tokens) { - std::string token; - - // parse first token - size_t pos = dvlab::str::str_get_token(line, token); - tokens.emplace_back(token); - - // parsing parenthesis - auto const left_paren_pos = line.find_first_of('(', pos); - auto const right_paren_pos = line.find_first_of(')', left_paren_pos == std::string::npos ? 0 : left_paren_pos); - auto const has_left_parenthesis = (left_paren_pos != std::string::npos); - auto const has_right_parenthesis = (right_paren_pos != std::string::npos); - - if (has_left_parenthesis) { - if (has_right_parenthesis) { - // coordinate string is given - pos = dvlab::str::str_get_token(line, token, left_paren_pos + 1, ','); - - if (pos == std::string::npos) { - _print_failed_at_line_no(); - spdlog::error("missing comma between declaration of qubit and column!!"); - return false; - } - - token = dvlab::str::trim_spaces(token); - if (token == "") { - _print_failed_at_line_no(); - spdlog::error("missing argument before comma!!"); - return false; - } - tokens.emplace_back(token); - - dvlab::str::str_get_token(line, token, pos + 1, ')'); - - token = dvlab::str::trim_spaces(token); - if (token == "") { - _print_failed_at_line_no(); - spdlog::error("missing argument before right parenthesis!!"); - return false; - } - tokens.emplace_back(token); - - pos = right_paren_pos + 1; - } else { - _print_failed_at_line_no(); - spdlog::error("missing closing parenthesis!!"); - return false; - } - } else { // if no left parenthesis - if (has_right_parenthesis) { - _print_failed_at_line_no(); - spdlog::error("missing opening parenthesis!!"); - return false; - } else { - // coordinate info is left out - tokens.emplace_back("-"); - tokens.emplace_back("-"); - } - } - - // parse remaining - pos = dvlab::str::str_get_token(line, token, pos); - - while (token.size()) { - tokens.emplace_back(token); - pos = dvlab::str::str_get_token(line, token, pos); - } - - return true; -} - -/** - * @brief Parse type and id - * - * @param token - * @param type - * @param id - * @return true - * @return false - */ -std::optional> ZXFileParser::_parse_type_and_id(std::string const& token) { - auto type = dvlab::str::toupper(token[0]); - - if (type == 'G') { - _print_failed_at_line_no(); - spdlog::error("ground vertices are not supported yet!!"); - return std::nullopt; - } - - if (supported_vertex_type.find(type) == std::string::npos) { - _print_failed_at_line_no(); - spdlog::error("unsupported vertex type ({})!!", type); - return std::nullopt; - } - - auto const id_string = token.substr(1); - - if (id_string.empty()) { - _print_failed_at_line_no(); - spdlog::error("Missing vertex ID after vertex type declaration ({})!!", type); - return std::nullopt; - } - - auto id = dvlab::str::from_string(id_string); - - if (!id.has_value()) { - _print_failed_at_line_no(); - spdlog::error("vertex ID ({}) is not an unsigned integer!!", id_string); - return std::nullopt; - } - - if (_storage.contains(id.value())) { - _print_failed_at_line_no(); - spdlog::error("duplicated vertex ID ({})!!", id); - return std::nullopt; - } - - return std::make_optional>({type, id.value()}); -} - -/** - * @brief Check the tokens are valid for boundary vertices - * - * @param tokens - * @return true - * @return false - */ -bool ZXFileParser::_is_valid_tokens_for_boundary_vertex(std::vector const& tokens) { - if (tokens[1] == "-") { - _print_failed_at_line_no(); - spdlog::error("please specify the qubit ID to boundary vertex!!"); - return false; - } - - if (tokens.size() <= 3) return true; - - if (Phase::from_string(tokens.back()).has_value()) { - _print_failed_at_line_no(); - spdlog::error("cannot assign phase to boundary vertex!!"); - return false; - } - return true; -} - -/** - * @brief Check the tokens are valid for H boxes - * - * @param tokens - * @return true - * @return false - */ -bool ZXFileParser::_is_valid_tokens_for_h_box(std::vector const& tokens) { - if (tokens.size() <= 3) return true; - - if (Phase::from_string(tokens.back()).has_value()) { - _print_failed_at_line_no(); - spdlog::error("cannot assign phase to H-box!!"); - return false; - } - return true; -} - -/** - * @brief Parse qubit - * - * @param token - * @param type input or output - * @param qubit will store the qubit after parsing - * @return true - * @return false - */ -bool ZXFileParser::_parse_qubit(std::string const& token, char const& type, int& qubit) { - if (token == "-") { - qubit = 0; - return true; - } - - if (!dvlab::str::str_to_i(token, qubit)) { - _print_failed_at_line_no(); - spdlog::error("qubit ID ({}) is not an integer!!", token); - return false; - } - - if (type == 'I') { - if (_taken_input_qubits.contains(qubit)) { - _print_failed_at_line_no(); - spdlog::error("duplicated input qubit ID ({})!!", qubit); - return false; - } - _taken_input_qubits.insert(qubit); - } - - if (type == 'O') { - if (_taken_output_qubits.contains(qubit)) { - _print_failed_at_line_no(); - spdlog::error("duplicated output qubit ID ({})!!", qubit); - return false; - } - _taken_output_qubits.insert(qubit); - } - - return true; -} - -/** - * @brief Parse column - * - * @param token - * @param column will store the column after parsing - * @return true - * @return false - */ -bool ZXFileParser::_parse_column(std::string const& token, float& column) { - if (token == "-") { - column = 0; - return true; - } - - if (!dvlab::str::str_to_f(token, column)) { - _print_failed_at_line_no(); - spdlog::error("column ID ({}) is not an unsigned integer!!", token); - return false; - } - - return true; -} - -/** - * @brief Parser the neighbor - * - * @param token - * @param neighbor will store the neighbor(s) after parsing - * @return true - * @return false - */ -bool ZXFileParser::_parse_neighbors(std::string const& token, std::pair& neighbor) { - auto const type = dvlab::str::toupper(token[0]); - unsigned id = 0; - if (supported_edge_type.find(type) == std::string::npos) { - _print_failed_at_line_no(); - spdlog::error("unsupported edge type ({})!!", type); - return false; - } - - auto const neighbor_string = token.substr(1); - - if (neighbor_string.empty()) { - _print_failed_at_line_no(); - spdlog::error("Missing neighbor vertex ID after edge type declaration ({})!!", type); - return false; - } - - if (!dvlab::str::str_to_u(neighbor_string, id)) { - _print_failed_at_line_no(); - spdlog::error("neighbor vertex ID ({}) is not an unsigned integer!!", neighbor_string); - return false; - } - - neighbor = {type, id}; - return true; -} - -/** - * @brief Print the line failed - * - */ -void ZXFileParser::_print_failed_at_line_no() const { - spdlog::error("Error: failed to read line {}!!", _line_no); -} - -} // namespace zx - -} // namespace qsyn diff --git a/src/zx/zx_file_parser.hpp b/src/zx/zx_file_parser.hpp deleted file mode 100644 index 89f028de..00000000 --- a/src/zx/zx_file_parser.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - PackageName [ zx ] - Synopsis [ Define zxFileParser structure ] - Author [ Design Verification Lab ] - Copyright [ Copyright(c) 2023 DVLab, GIEE, NTU, Taiwan ] -****************************************************************************/ - -#pragma once - -#include -#include -#include -#include - -#include "./zx_def.hpp" - -namespace qsyn { - -namespace zx { - -class ZXFileParser { -public: - using VertexInfo = detail::VertexInfo; - using StorageType = detail::StorageType; - - ZXFileParser() {} - - bool parse(std::filesystem::path const& filename); - StorageType get_storage() const { return _storage; } - -private: - unsigned _line_no = 1; - StorageType _storage; - std::unordered_set _taken_input_qubits; - std::unordered_set _taken_output_qubits; - - bool _parse_internal(std::ifstream& f); - - // parsing subroutines - bool _tokenize(std::string const& line, std::vector& tokens); - - std::optional> _parse_type_and_id(std::string const& token); - bool _is_valid_tokens_for_boundary_vertex(std::vector const& tokens); - bool _is_valid_tokens_for_h_box(std::vector const& tokens); - - bool _parse_qubit(std::string const& token, char const& type, int& qubit); - bool _parse_column(std::string const& token, float& column); - - bool _parse_neighbors(std::string const& token, std::pair& neighbor); - - void _print_failed_at_line_no() const; -}; - -} // namespace zx - -} // namespace qsyn diff --git a/src/zx/zx_io.cpp b/src/zx/zx_io.cpp index acc06305..903bc452 100644 --- a/src/zx/zx_io.cpp +++ b/src/zx/zx_io.cpp @@ -6,6 +6,7 @@ ****************************************************************************/ #include +#include #include #include @@ -18,13 +19,415 @@ #include #include -#include "./zx_file_parser.hpp" #include "./zxgraph.hpp" #include "util/sysdep.hpp" #include "util/tmp_files.hpp" +#include "util/util.hpp" namespace qsyn::zx { +namespace detail { + +struct VertexInfo { + char type = 'Z'; + QubitIdType qubit = 0; + float row = 0.f; + float column = 0.f; + std::vector> neighbors; + Phase phase; +}; + +using StorageType = dvlab::utils::ordered_hashmap; + +class ZXFileParser { +public: + std::optional parse(std::istream& f); + + static constexpr std::string_view supported_vertex_type = "IOZXH"; + static constexpr std::string_view supported_edge_type = "SH"; + +private: + size_t _line_no = 1; + std::unordered_set _taken_input_qubits; + std::unordered_set _taken_output_qubits; + + // parsing subroutines + bool _tokenize(std::string const& line, std::vector& tokens); + + std::optional> _parse_type_and_id(StorageType const& storage, std::string const& token); + + bool _parse_row(std::string const& token, float& row); + bool _parse_column(std::string const& token, float& column); + + bool _parse_neighbors(std::string const& token, std::pair& neighbor); + + void _print_failed_at_line_no() const { + spdlog::error("Error: failed to read line {}!!", _line_no); + } +}; + +/** + * @brief Parse each line in the istream + * + * @param f + * @return true if the file is successfully parsed + * @return false if the format of any lines are wrong + */ +std::optional ZXFileParser::parse(std::istream& f) { + // each line should be in the format of + // [()] [<...] [size_t qubit_id] + // [()] [<...] [Phase phase] + auto storage = StorageType{}; + _taken_input_qubits.clear(); + _taken_output_qubits.clear(); + _line_no = 1; + + QubitIdType max_input_qubit_id = 0; + QubitIdType max_output_qubit_id = 0; + + for (std::string line; std::getline(f, line); _line_no++) { + line = dvlab::str::trim_spaces(dvlab::str::trim_comments(line)); + if (line.empty()) continue; + + std::vector tokens; + if (!_tokenize(line, tokens)) return std::nullopt; + + VertexInfo info; + + auto const type_and_id = _parse_type_and_id(storage, tokens[0]); + if (!type_and_id) return std::nullopt; + + info.type = type_and_id->first; + auto id = type_and_id->second; + + if (info.type == 'H') info.phase = Phase(1); + + switch (info.type) { + case 'I': { + if (auto const qubit = dvlab::str::from_string(tokens.back()); qubit.has_value() && tokens.size() > 3) { + tokens.pop_back(); + info.qubit = qubit.value(); + max_input_qubit_id = std::max(max_input_qubit_id, info.qubit); + } else { + info.qubit = max_input_qubit_id++; + } + if (_taken_input_qubits.contains(info.qubit)) { + _print_failed_at_line_no(); + spdlog::error("duplicated input qubit ID ({})!!", info.qubit); + return std::nullopt; + } + _taken_input_qubits.insert(info.qubit); + info.row = static_cast(info.qubit); + break; + } + case 'O': { + if (auto const qubit = dvlab::str::from_string(tokens.back()); qubit.has_value() && tokens.size() > 3) { + tokens.pop_back(); + info.qubit = qubit.value(); + max_output_qubit_id = std::max(max_output_qubit_id, info.qubit); + } else { + info.qubit = max_output_qubit_id++; + } + if (_taken_output_qubits.contains(info.qubit)) { + _print_failed_at_line_no(); + spdlog::error("duplicated output qubit ID ({})!!", info.qubit); + return std::nullopt; + } + info.row = static_cast(info.qubit); + break; + } + default: { + if (auto const phase = Phase::from_string(tokens.back()); phase.has_value() && tokens.size() > 3) { + tokens.pop_back(); + info.phase = phase.value(); + } + info.row = 0; + break; + } + } + + if (!_parse_row(tokens[1], info.row)) return std::nullopt; + if (!_parse_column(tokens[2], info.column)) return std::nullopt; + + std::pair neighbor; + for (size_t i = 3; i < tokens.size(); ++i) { + if (!_parse_neighbors(tokens[i], neighbor)) return std::nullopt; + info.neighbors.emplace_back(neighbor); + } + + storage.emplace(id, info); + } + + return storage; +} + +/** + * @brief Tokenize the line + * + * @param line + * @param tokens + * @return true + * @return false + */ +bool ZXFileParser::_tokenize(std::string const& line, std::vector& tokens) { + std::string token; + + // parse first token + size_t pos = dvlab::str::str_get_token(line, token); + tokens.emplace_back(token); + + // parsing parenthesis + + enum struct ParenthesisCase { + none, + both, + left, + right + }; + + auto const left_paren_pos = line.find_first_of('(', pos); + auto const right_paren_pos = line.find_first_of(')', left_paren_pos == std::string::npos ? 0 : left_paren_pos); + + auto const parenthesis_case = std::invoke([&]() -> ParenthesisCase { + auto const has_left_parenthesis = (left_paren_pos != std::string::npos); + auto const has_right_parenthesis = (right_paren_pos != std::string::npos); + if (has_left_parenthesis && has_right_parenthesis) return ParenthesisCase::both; + if (has_left_parenthesis && !has_right_parenthesis) return ParenthesisCase::left; + if (!has_left_parenthesis && has_right_parenthesis) return ParenthesisCase::right; + return ParenthesisCase::none; + }); + + switch (parenthesis_case) { + case ParenthesisCase::none: + // coordinate info is left out + tokens.emplace_back("-"); + tokens.emplace_back("-"); + break; + case ParenthesisCase::left: + _print_failed_at_line_no(); + spdlog::error("missing closing parenthesis!!"); + return false; + break; + case ParenthesisCase::right: + _print_failed_at_line_no(); + spdlog::error("missing opening parenthesis!!"); + return false; + break; + case ParenthesisCase::both: + pos = dvlab::str::str_get_token(line, token, left_paren_pos + 1, ','); + + if (pos == std::string::npos) { + _print_failed_at_line_no(); + spdlog::error("missing comma between declaration of qubit and column!!"); + return false; + } + + token = dvlab::str::trim_spaces(token); + if (token == "") { + _print_failed_at_line_no(); + spdlog::error("missing argument before comma!!"); + return false; + } + tokens.emplace_back(token); + + dvlab::str::str_get_token(line, token, pos + 1, ')'); + + token = dvlab::str::trim_spaces(token); + if (token == "") { + _print_failed_at_line_no(); + spdlog::error("missing argument before right parenthesis!!"); + return false; + } + tokens.emplace_back(token); + + pos = right_paren_pos + 1; + break; + } + + // parse remaining + pos = dvlab::str::str_get_token(line, token, pos); + + while (token.size()) { + tokens.emplace_back(token); + pos = dvlab::str::str_get_token(line, token, pos); + } + + return true; +} + +/** + * @brief Parse type and id + * + * @param token + * @param type + * @param id + * @return true + * @return false + */ +std::optional> ZXFileParser::_parse_type_and_id(StorageType const& storage, std::string const& token) { + auto type = dvlab::str::toupper(token[0]); + + if (type == 'G') { + _print_failed_at_line_no(); + spdlog::error("ground vertices are not supported yet!!"); + return std::nullopt; + } + + if (supported_vertex_type.find(type) == std::string::npos) { + _print_failed_at_line_no(); + spdlog::error("unsupported vertex type ({})!!", type); + return std::nullopt; + } + + auto const id_string = token.substr(1); + + if (id_string.empty()) { + _print_failed_at_line_no(); + spdlog::error("Missing vertex ID after vertex type declaration ({})!!", type); + return std::nullopt; + } + + auto id = dvlab::str::from_string(id_string); + + if (!id) { + _print_failed_at_line_no(); + spdlog::error("vertex ID ({}) is not an unsigned integer!!", id_string); + return std::nullopt; + } + + if (storage.contains(id.value())) { + _print_failed_at_line_no(); + spdlog::error("duplicated vertex ID ({})!!", id); + return std::nullopt; + } + + return std::make_optional>({type, id.value()}); +} + +/** + * @brief Parse qubit + * + * @param token + * @param type input or output + * @param qubit will store the qubit after parsing + * @return true + * @return false + */ +bool ZXFileParser::_parse_row(std::string const& token, float& row) { + if (token == "-") { + return true; + } + + if (!dvlab::str::str_to_f(token, row)) { + _print_failed_at_line_no(); + spdlog::error("row ({}) is not an floating-point number!!", token); + return false; + } + + return true; +} + +/** + * @brief Parse column + * + * @param token + * @param column will store the column after parsing + * @return true + * @return false + */ +bool ZXFileParser::_parse_column(std::string const& token, float& column) { + if (token == "-") { + column = 0; + return true; + } + + if (!dvlab::str::str_to_f(token, column)) { + _print_failed_at_line_no(); + spdlog::error("column ({}) is not an floating-point number!!", token); + return false; + } + + return true; +} + +/** + * @brief Parser the neighbor + * + * @param token + * @param neighbor will store the neighbor(s) after parsing + * @return true + * @return false + */ +bool ZXFileParser::_parse_neighbors(std::string const& token, std::pair& neighbor) { + auto const type = dvlab::str::toupper(token[0]); + unsigned id = 0; + if (supported_edge_type.find(type) == std::string::npos) { + _print_failed_at_line_no(); + spdlog::error("unsupported edge type ({})!!", type); + return false; + } + + auto const neighbor_string = token.substr(1); + + if (neighbor_string.empty()) { + _print_failed_at_line_no(); + spdlog::error("Missing neighbor vertex ID after edge type declaration ({})!!", type); + return false; + } + + if (!dvlab::str::str_to_u(neighbor_string, id)) { + _print_failed_at_line_no(); + spdlog::error("neighbor vertex ID ({}) is not an unsigned integer!!", neighbor_string); + return false; + } + + neighbor = {type, id}; + return true; +} + +std::optional build_graph_from_parser_storage(StorageType const& storage, bool keep_id) { + ZXGraph graph; + std::unordered_map id2_vertex; + + for (auto& [id, info] : storage) { + ZXVertex* v = std::invoke( + // clang++ does not support structured binding capture by reference with OpenMP + [&info = info, &graph]() { + switch (info.type) { + case 'I': + return graph.add_input(info.qubit, info.row, info.column); + case 'O': + return graph.add_output(info.qubit, info.row, info.column); + case 'Z': + return graph.add_vertex(VertexType::z, info.phase, info.row, info.column); + case 'X': + return graph.add_vertex(VertexType::x, info.phase, info.row, info.column); + case 'H': + return graph.add_vertex(VertexType::h_box, info.phase, info.row, info.column); + default: + DVLAB_UNREACHABLE("unsupported vertex type"); + } + }); + + if (keep_id) v->set_id(id); + id2_vertex[id] = v; + } + + for (auto& [vid, info] : storage) { + for (auto& [type, nbid] : info.neighbors) { + if (!id2_vertex.contains(nbid)) { + spdlog::error("failed to build the graph: cannot find vertex with ID {}!!", nbid); + return std::nullopt; + } + auto const etype = (type == 'S') ? EdgeType::simple : EdgeType::hadamard; + if (graph.is_neighbor(id2_vertex[vid], id2_vertex[nbid], etype)) continue; + graph.add_edge(id2_vertex[vid], id2_vertex[nbid], etype); + } + } + return graph; +} + +} // namespace detail /** * @brief Read a ZXGraph * @@ -33,18 +436,33 @@ namespace qsyn::zx { * @return true if correctly constructed the graph * @return false */ -bool ZXGraph::read_zx(std::filesystem::path const& filepath, bool keep_id) { - // REVIEW - should we guard the case of no file extension? - if (filepath.has_extension()) { - if (filepath.extension() != ".zx") { - fmt::println("unsupported file extension \"{}\"!!", filepath.extension().string()); - return false; - } +std::optional from_zx(std::filesystem::path const& filepath, bool keep_id) { + std::ifstream zx_file(filepath); + + if (!zx_file.is_open()) { + spdlog::error("Cannot open the file \"{}\"!!", filepath); + return std::nullopt; + } + + auto const storage = detail::ZXFileParser{}.parse(zx_file); + + if (!storage) { + spdlog::error("failed to parse the file \"{}\"!!", filepath.string()); + return std::nullopt; } - ZXFileParser parser; + return build_graph_from_parser_storage(storage.value(), keep_id); +} + +std::optional from_zx(std::istream& istr, bool keep_id) { + auto const storage = detail::ZXFileParser{}.parse(istr); + + if (!storage) { + spdlog::error("failed to parse the input stream!!"); + return std::nullopt; + } - return parser.parse(filepath.string()) && _build_graph_from_parser_storage(parser.get_storage(), keep_id); + return build_graph_from_parser_storage(storage.value(), keep_id); } /** @@ -113,7 +531,7 @@ bool ZXGraph::write_zx(std::filesystem::path const& filename, bool complete) con : v->is_x() ? "X" : "H", v->get_id(), - v->get_qubit(), + v->get_row(), floor(v->get_col())); if (!write_neighbors(v)) { @@ -129,53 +547,6 @@ bool ZXGraph::write_zx(std::filesystem::path const& filename, bool complete) con return true; } -/** - * @brief Build graph from parser storage - * - * @param storage - * @param keepID - * @return true - * @return false - */ -bool ZXGraph::_build_graph_from_parser_storage(detail::StorageType const& storage, bool keep_id) { - std::unordered_map id2_vertex; - - for (auto& [id, info] : storage) { - ZXVertex* v = std::invoke( - // clang++ does not support structured binding capture by reference with OpenMP - [&info = info, this]() { - if (info.type == 'I') - return add_input(info.qubit, info.column); - if (info.type == 'O') - return add_output(info.qubit, info.column); - VertexType vtype = VertexType::boundary; - if (info.type == 'Z') - vtype = VertexType::z; - else if (info.type == 'X') - vtype = VertexType::x; - else - vtype = VertexType::h_box; - return add_vertex(info.qubit, vtype, info.phase, info.column); - }); - - if (keep_id) v->set_id(id); - id2_vertex[id] = v; - } - - for (auto& [vid, info] : storage) { - for (auto& [type, nbid] : info.neighbors) { - if (!id2_vertex.contains(nbid)) { - spdlog::error("failed to build the graph: cannot find vertex with ID {}!!", nbid); - return false; - } - auto const etype = (type == 'S') ? EdgeType::simple : EdgeType::hadamard; - if (this->is_neighbor(id2_vertex[vid], id2_vertex[nbid], etype)) continue; - add_edge(id2_vertex[vid], id2_vertex[nbid], etype); - } - } - return true; -} - /** * @brief Generate tikz file * @@ -277,7 +648,7 @@ bool ZXGraph::write_tikz(std::ostream& os) const { fmt::println(os, " % vertices"); // drawing vertices: \node[zspi] (88888) at (0,1) {{\tiny 88888}}; for (auto& v : get_vertices()) { - fmt::println(os, " \\node[{0}]({1}) at ({2}, {3}) {{{{\\{4} {1}}}}};", get_attr_string(v), v->get_id(), v->get_col(), v->get_qubit(), font_size); + fmt::println(os, " \\node[{0}]({1}) at ({2}, {3}) {{{{\\{4} {1}}}}};", get_attr_string(v), v->get_id(), v->get_col(), v->get_row(), font_size); } // end for vertices fmt::println(os, ""); fmt::println(os, " % edges"); @@ -285,7 +656,7 @@ bool ZXGraph::write_tikz(std::ostream& os) const { for (auto& v : _vertices) { for (auto& [n, e] : this->get_neighbors(v)) { if (n->get_id() > v->get_id()) { - if (n->get_col() == v->get_col() && n->get_qubit() == v->get_qubit()) { + if (n->get_col() == v->get_col() && n->get_row() == v->get_row()) { spdlog::warn("{} and {} are connected but they have same coordinates.", v->get_id(), n->get_id()); fmt::println(os, " % \\draw[{0}] ({1}) -- ({2});", et2s.at(e), v->get_id(), n->get_id()); } else { diff --git a/src/zx/zx_io.hpp b/src/zx/zx_io.hpp new file mode 100644 index 00000000..48fb408c --- /dev/null +++ b/src/zx/zx_io.hpp @@ -0,0 +1,25 @@ +/** + * @file + * @author Design Verification Lab + * @brief define read/write functions for ZXGraph + * + * @copyright Copyright(c) 2024 DVLab, GIEE, NTU, Taiwan + * + */ + +#pragma once + +#include + +#include "./zxgraph.hpp" + +namespace qsyn { + +namespace zx { + +std::optional from_zx(std::filesystem::path const& filename, bool keep_id = false); +std::optional from_zx(std::istream& istr, bool keep_id = false); + +} // namespace zx + +} // namespace qsyn diff --git a/src/zx/zx_partition.cpp b/src/zx/zx_partition.cpp index 2119f9d6..45741c75 100644 --- a/src/zx/zx_partition.cpp +++ b/src/zx/zx_partition.cpp @@ -77,7 +77,7 @@ std::pair, std::vector> ZXGraph::create_subgraphs(s std::vector neighbors_to_add; for (auto const& [neighbor, edgeType] : this->get_neighbors(vertex)) { if (!partition.contains(neighbor)) { - auto boundary = new ZXVertex(next_vertex_id++, next_boundary_qubit_id++, VertexType::boundary); + auto boundary = new ZXVertex(next_vertex_id++, next_boundary_qubit_id++, VertexType::boundary, Phase(), 0, 0); inner_cuts.emplace(vertex, neighbor, edgeType); cut_to_boundary[{vertex, neighbor, edgeType}] = boundary; diff --git a/src/zx/zxgraph.cpp b/src/zx/zxgraph.cpp index 2d79f52d..f3dc5c73 100644 --- a/src/zx/zxgraph.cpp +++ b/src/zx/zxgraph.cpp @@ -14,6 +14,7 @@ #include #include "./zx_def.hpp" +#include "qsyn/qsyn_type.hpp" #include "tl/enumerate.hpp" #include "util/boolean_matrix.hpp" @@ -49,21 +50,22 @@ ZXGraph::ZXGraph(ZXVertexList const& vertices, } ZXGraph::ZXGraph(ZXGraph const& other) : _filename{other._filename}, _procedures{other._procedures} { - std::unordered_map old_v2new_v_map; + std::unordered_map old_to_new_vertex_map; for (auto& v : other._vertices) { if (v->is_boundary()) { - if (other._inputs.contains(v)) - old_v2new_v_map[v] = this->add_input(v->get_qubit(), v->get_col()); - else - old_v2new_v_map[v] = this->add_output(v->get_qubit(), v->get_col()); + if (other._inputs.contains(v)) { + old_to_new_vertex_map[v] = this->add_input(v->get_qubit(), v->get_col()); + } else { + old_to_new_vertex_map[v] = this->add_output(v->get_qubit(), v->get_col()); + } } else if (v->is_z() || v->is_x() || v->is_hbox()) { - old_v2new_v_map[v] = this->add_vertex(v->get_qubit(), v->get_type(), v->get_phase(), v->get_col()); + old_to_new_vertex_map[v] = this->add_vertex(v->get_type(), v->get_phase(), v->get_row(), v->get_col()); } } - other.for_each_edge([&old_v2new_v_map, this](EdgePair const& epair) { - this->add_edge(old_v2new_v_map[epair.first.first], old_v2new_v_map[epair.first.second], epair.second); + other.for_each_edge([&old_to_new_vertex_map, this](EdgePair const& epair) { + this->add_edge(old_to_new_vertex_map[epair.first.first], old_to_new_vertex_map[epair.first.second], epair.second); }); } @@ -206,34 +208,33 @@ double ZXGraph::density() { /* class ZXGraph Add functions */ /*****************************************************/ -/** - * @brief Add input to the ZXGraph - * - * @param qubit - * @param col - * @return ZXVertex* - */ -ZXVertex* ZXGraph::add_input(QubitIdType qubit, ColumnIdType col) { +ZXVertex* ZXGraph::add_input(QubitIdType qubit, float col) { + return add_input(qubit, static_cast(qubit), col); +} + +ZXVertex* ZXGraph::add_input(QubitIdType qubit, float row, float col) { assert(!is_input_qubit(qubit)); - ZXVertex* v = add_vertex(qubit, VertexType::boundary, Phase(), col); + auto v = new ZXVertex(_next_v_id, qubit, VertexType::boundary, Phase(), row, col); _inputs.emplace(v); _input_list.emplace(qubit, v); + _vertices.emplace(v); + _next_v_id++; return v; } -/** - * @brief Add output to the ZXGraph - * - * @param qubit - * @return ZXVertex* - */ -ZXVertex* ZXGraph::add_output(QubitIdType qubit, ColumnIdType col) { +ZXVertex* ZXGraph::add_output(QubitIdType qubit, float col) { + return add_output(qubit, static_cast(qubit), col); +} + +ZXVertex* ZXGraph::add_output(QubitIdType qubit, float row, float col) { assert(!is_output_qubit(qubit)); - ZXVertex* v = add_vertex(qubit, VertexType::boundary, Phase(), col); + auto v = new ZXVertex(_next_v_id, qubit, VertexType::boundary, Phase(), row, col); _outputs.emplace(v); _output_list.emplace(qubit, v); + _vertices.emplace(v); + _next_v_id++; return v; } @@ -245,8 +246,8 @@ ZXVertex* ZXGraph::add_output(QubitIdType qubit, ColumnIdType col) { * @param phase the phase * @return ZXVertex* */ -ZXVertex* ZXGraph::add_vertex(QubitIdType qubit, VertexType vt, Phase phase, ColumnIdType col) { - auto v = new ZXVertex(_next_v_id, qubit, vt, phase, col); +ZXVertex* ZXGraph::add_vertex(VertexType vt, Phase phase, float row, float col) { + auto v = new ZXVertex(_next_v_id, 0, vt, phase, row, col); _vertices.emplace(v); _next_v_id++; return v; @@ -276,9 +277,9 @@ void ZXGraph::add_edge(ZXVertex* vs, ZXVertex* vt, EdgeType et) { // and connect the new vertex to both vs and vt if (vs->is_hbox() || vt->is_hbox()) { ZXVertex* v = add_vertex( - (vs->get_qubit() + vt->get_qubit()) / 2, et == EdgeType::hadamard ? VertexType::h_box : VertexType::z, et == EdgeType::hadamard ? Phase(1) : Phase(0), + (vs->get_row() + vt->get_row()) / 2, (vs->get_col() + vt->get_col()) / 2); vs->_neighbors.emplace(v, EdgeType::simple); v->_neighbors.emplace(vs, EdgeType::simple); @@ -460,7 +461,7 @@ void ZXGraph::adjoint() { * @param phase */ void ZXGraph::assign_vertex_to_boundary(QubitIdType qubit, bool is_input, VertexType vtype, Phase phase) { - ZXVertex* v = add_vertex(qubit, vtype, phase); + ZXVertex* v = add_vertex(vtype, phase, gsl::narrow(qubit)); ZXVertex* boundary = is_input ? _input_list[qubit] : _output_list[qubit]; for (auto& [nb, etype] : this->get_neighbors(boundary)) { add_edge(v, nb, etype); @@ -477,11 +478,8 @@ void ZXGraph::assign_vertex_to_boundary(QubitIdType qubit, bool is_input, Vertex */ void ZXGraph::gadgetize_phase(ZXVertex* v, Phase const& keep_phase) { if (!v->is_z()) return; - ZXVertex* leaf = this->add_vertex(-2, VertexType::z, v->get_phase() - keep_phase); - ZXVertex* buffer = this->add_vertex(-1, VertexType::z, Phase(0)); - // REVIEW - No floating, directly take v - leaf->set_col(v->get_col()); - buffer->set_col(v->get_col()); + ZXVertex* leaf = this->add_vertex(VertexType::z, v->get_phase() - keep_phase, -2, v->get_col()); + ZXVertex* buffer = this->add_vertex(VertexType::z, Phase(0), -1, v->get_col()); v->set_phase(keep_phase); this->add_edge(leaf, buffer, EdgeType::hadamard); @@ -499,13 +497,11 @@ void ZXGraph::gadgetize_phase(ZXVertex* v, Phase const& keep_phase) { ZXVertex* ZXGraph::add_buffer(ZXVertex* vertex_to_protect, ZXVertex* vertex_other, EdgeType etype) { if (!this->is_neighbor(vertex_to_protect, vertex_other, etype)) return nullptr; - ZXVertex* buffer_vertex = this->add_vertex(vertex_to_protect->get_qubit(), VertexType::z, Phase(0)); + ZXVertex* buffer_vertex = this->add_vertex(VertexType::z, Phase(0), vertex_to_protect->get_row(), (vertex_to_protect->get_col() + vertex_other->get_col()) / 2); this->add_edge(vertex_to_protect, buffer_vertex, toggle_edge(etype)); this->add_edge(buffer_vertex, vertex_other, EdgeType::hadamard); this->remove_edge(vertex_to_protect, vertex_other, etype); - // REVIEW - Float version - buffer_vertex->set_col((vertex_to_protect->get_col() + vertex_other->get_col()) / 2); return buffer_vertex; } diff --git a/src/zx/zxgraph.hpp b/src/zx/zxgraph.hpp index 2d312295..f3b2c6ba 100644 --- a/src/zx/zxgraph.hpp +++ b/src/zx/zxgraph.hpp @@ -48,23 +48,24 @@ class ZXVertex { friend class ZXGraph; public: - using QubitIdType = qsyn::QubitIdType; - using ColumnIdType = double; + using QubitIdType = qsyn::QubitIdType; - ZXVertex(size_t id, QubitIdType qubit, VertexType vt, Phase phase = Phase(), ColumnIdType col = 0) - : _id{id}, _type{vt}, _qubit{qubit}, _phase{phase}, _col{col} {} + ZXVertex(size_t id, QubitIdType qubit, VertexType vt, Phase phase, float row, float col) + : _id{id}, _type{vt}, _qubit{qubit}, _phase{phase}, _row{row}, _col{col} {} // Getter and Setter size_t get_id() const { return _id; } QubitIdType get_qubit() const { return _qubit; } Phase const& get_phase() const { return _phase; } VertexType get_type() const { return _type; } - ColumnIdType get_col() const { return _col; } + float get_row() const { return _row; } + float get_col() const { return _col; } void set_id(size_t id) { _id = id; } void set_qubit(QubitIdType q) { _qubit = q; } void set_phase(Phase const& p) { _phase = p; } - void set_col(ColumnIdType c) { _col = c; } + void set_row(float r) { _row = r; } + void set_col(float c) { _col = c; } void set_type(VertexType vt) { _type = vt; } // Print functions @@ -83,16 +84,17 @@ class ZXVertex { friend class ZXGraph; size_t _id; VertexType _type; - QubitIdType _qubit; + QubitIdType _qubit; // for boundary vertices, this is the qubit id; for non-boundary vertices, + // this is a dummy value that may be used to mark temporary information Phase _phase; - ColumnIdType _col; + float _row; + float _col; Neighbors _neighbors; }; class ZXGraph { // NOLINT(cppcoreguidelines-special-member-functions) : copy-swap idiom public: - using QubitIdType = ZXVertex::QubitIdType; - using ColumnIdType = ZXVertex::ColumnIdType; + using QubitIdType = ZXVertex::QubitIdType; ZXGraph() {} @@ -195,9 +197,11 @@ class ZXGraph { // NOLINT(cppcoreguidelines-special-member-functions) : copy-sw inline size_t non_clifford_t_count() const { return non_clifford_count() - t_count(); } // Add and Remove - ZXVertex* add_input(QubitIdType qubit, ColumnIdType col = 0); - ZXVertex* add_output(QubitIdType qubit, ColumnIdType col = 0); - ZXVertex* add_vertex(QubitIdType qubit, VertexType vt, Phase phase = Phase(), ColumnIdType col = 0); + ZXVertex* add_input(QubitIdType qubit, float col = 0.f); + ZXVertex* add_input(QubitIdType qubit, float row, float col); + ZXVertex* add_output(QubitIdType qubit, float col = 0.f); + ZXVertex* add_output(QubitIdType qubit, float row, float col); + ZXVertex* add_vertex(VertexType vt, Phase phase = Phase(), float row = 0.f, float col = 0.f); void add_edge(ZXVertex* vs, ZXVertex* vt, EdgeType et); size_t remove_isolated_vertices(); @@ -241,11 +245,10 @@ class ZXGraph { // NOLINT(cppcoreguidelines-special-member-functions) : copy-sw void print_io() const; void print_vertices(spdlog::level::level_enum lvl = spdlog::level::level_enum::off) const; void print_vertices(std::vector cand) const; - void print_vertices_by_qubits(spdlog::level::level_enum lvl = spdlog::level::level_enum::off, QubitIdList cand = {}) const; + void print_vertices_by_rows(spdlog::level::level_enum lvl = spdlog::level::level_enum::off, std::vector cand = {}) const; void print_edges() const; void print_difference(ZXGraph* other) const; - void draw() const; // For mapping (in zxMapping.cpp) ZXVertexList get_non_boundary_vertices(); @@ -256,7 +259,6 @@ class ZXGraph { // NOLINT(cppcoreguidelines-special-member-functions) : copy-sw std::unordered_map const& get_output_list() const { return _output_list; } // I/O (in zxIO.cpp) - bool read_zx(std::filesystem::path const& filepath, bool keep_id = false); bool write_zx(std::filesystem::path const& filename, bool complete = false) const; bool write_tikz(std::string const& filename) const; bool write_tikz(std::ostream& os) const; @@ -302,8 +304,6 @@ class ZXGraph { // NOLINT(cppcoreguidelines-special-member-functions) : copy-sw void _dfs(std::unordered_set& visited_vertices, std::vector& topological_order, ZXVertex* v) const; void _bfs(std::unordered_set& visited_vertices, std::vector& topological_order, ZXVertex* v) const; - bool _build_graph_from_parser_storage(detail::StorageType const& storage, bool keep_id = false); - void _move_vertices_from(ZXGraph& other); }; diff --git a/src/zx/zxgraph_action.cpp b/src/zx/zxgraph_action.cpp index 98c30d3f..0241cce9 100644 --- a/src/zx/zxgraph_action.cpp +++ b/src/zx/zxgraph_action.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "./zx_def.hpp" #include "./zxgraph.hpp" @@ -52,7 +53,14 @@ void ZXGraph::toggle_vertex(ZXVertex* v) { */ void ZXGraph::lift_qubit(int n) { for (auto const& v : _vertices) { - v->set_qubit(v->get_qubit() + n); + v->set_row(v->get_row() + static_cast(n)); + } + + for (auto const& i : _inputs) { + i->set_qubit(i->get_qubit() + n); + } + for (auto const& o : _outputs) { + o->set_qubit(o->get_qubit() + n); } std::unordered_map new_input_list, new_output_list; @@ -90,7 +98,7 @@ ZXGraph& ZXGraph::compose(ZXGraph const& target) { // Update `_col` of copiedGraph to make them unique to the original graph for (auto const& v : copied_graph.get_vertices()) { - v->set_col(v->get_col() + max_col + 1); + v->set_col(v->get_col() + static_cast(max_col) + 1); } // Sort ori-output and copy-input @@ -205,8 +213,8 @@ void ZXGraph::add_gadget(Phase p, std::vector const& vertices) { if (vertices[i]->get_type() == VertexType::boundary || vertices[i]->get_type() == VertexType::h_box) return; } - ZXVertex* axel = add_vertex(-1, VertexType::z, Phase(0)); - ZXVertex* leaf = add_vertex(-2, VertexType::z, p); + ZXVertex* axel = add_vertex(VertexType::z, Phase(0), -1); + ZXVertex* leaf = add_vertex(VertexType::z, p, -2); add_edge(axel, leaf, EdgeType::hadamard); for (auto const& v : vertices) add_edge(v, axel, EdgeType::hadamard); @@ -241,8 +249,8 @@ std::unordered_map ZXGraph::create_id_to_vertex_map() const { */ void ZXGraph::adjust_vertex_coordinates() { // FIXME - QubitId -> RowId - std::unordered_map> qubit_id_to_vertices_map; - std::unordered_set visited_qubit_ids; + std::unordered_map> row_to_vertices_map; + std::unordered_set visited_rows; std::vector vertex_queue; // NOTE - Check Gadgets // FIXME - When replacing QubitId with RowId, add 0.5 on it @@ -264,47 +272,51 @@ void ZXGraph::adjust_vertex_coordinates() { for (auto const& i : _inputs) { vertex_queue.emplace_back(i); - visited_qubit_ids.insert(gsl::narrow(i->get_id())); + visited_rows.insert(gsl::narrow(i->get_id())); } while (!vertex_queue.empty()) { ZXVertex* v = vertex_queue.front(); vertex_queue.erase(vertex_queue.begin()); - qubit_id_to_vertices_map[v->get_qubit()].emplace_back(v); + row_to_vertices_map[v->get_row()].emplace_back(v); for (auto const& nb : get_neighbors(v) | std::views::keys) { - if (visited_qubit_ids.find(gsl::narrow(nb->get_id())) == visited_qubit_ids.end()) { + if (visited_rows.find(gsl::narrow(nb->get_id())) == visited_rows.end()) { vertex_queue.emplace_back(nb); - visited_qubit_ids.insert(gsl::narrow(nb->get_id())); + visited_rows.insert(gsl::narrow(nb->get_id())); } } } std::vector gadgets; - double non_gadget = 0; - for (size_t i = 0; i < qubit_id_to_vertices_map[-2].size(); i++) { - if (get_num_neighbors(qubit_id_to_vertices_map[-2][i]) == 1) { // Not Gadgets - gadgets.emplace_back(qubit_id_to_vertices_map[-2][i]); + float non_gadget = 0; + for (size_t i = 0; i < row_to_vertices_map[-2].size(); i++) { + if (get_num_neighbors(row_to_vertices_map[-2][i]) == 1) { // Not Gadgets + gadgets.emplace_back(row_to_vertices_map[-2][i]); } else non_gadget++; } - auto end_it = std::remove_if( - qubit_id_to_vertices_map[-2].begin(), - qubit_id_to_vertices_map[-2].end(), - [this](ZXVertex* v) { - return this->get_num_neighbors(v) == 1; + std::erase_if(row_to_vertices_map[-2], [this](ZXVertex* v) { return this->get_num_neighbors(v) == 1; }); + + row_to_vertices_map[-2].insert(row_to_vertices_map[-2].end(), gadgets.begin(), gadgets.end()); + + for (auto const& [qid, vertices] : row_to_vertices_map) { + auto col = std::invoke([qid = qid, non_gadget]() -> float { + if (qid == -2) return 0.5; + if (qid == -1) return 0.5f + non_gadget; + return 0.0f; }); - qubit_id_to_vertices_map[-2].erase(end_it, qubit_id_to_vertices_map[-2].end()); - - qubit_id_to_vertices_map[-2].insert(qubit_id_to_vertices_map[-2].end(), gadgets.begin(), gadgets.end()); - double max_col = 0.0; - for (auto& i : qubit_id_to_vertices_map) { - double col = i.first == -2 ? 0.5 : i.first == -1 ? 0.5 + non_gadget - : 0.0; - for (auto& v : i.second) { + for (auto const& v : vertices) { v->set_col(col); col++; } - col--; - max_col = std::max(max_col, std::ceil(col)); } + + auto const max_col = std::ceil( + std::ranges::max( + row_to_vertices_map | + std::views::values | + std::views::transform([](std::vector const& v) { + return std::ranges::max(v | std::views::transform([](ZXVertex* v) { return v->get_col(); })); + }))); + for (auto& o : _outputs) o->set_col(max_col); } diff --git a/src/zx/zxgraph_print.cpp b/src/zx/zxgraph_print.cpp index 31a1c63d..3c7c167c 100644 --- a/src/zx/zxgraph_print.cpp +++ b/src/zx/zxgraph_print.cpp @@ -89,13 +89,13 @@ void ZXGraph::print_vertices(std::vector cand) const { * * @param cand */ -void ZXGraph::print_vertices_by_qubits(spdlog::level::level_enum lvl, QubitIdList cand) const { - std::map> q2_vmap; +void ZXGraph::print_vertices_by_rows(spdlog::level::level_enum lvl, std::vector cand) const { + std::map> q2_vmap; for (auto const& v : _vertices) { - if (!q2_vmap.contains(v->get_qubit())) { - q2_vmap.emplace(v->get_qubit(), std::vector(1, v)); + if (!q2_vmap.contains(v->get_row())) { + q2_vmap.emplace(v->get_row(), std::vector(1, v)); } else { - q2_vmap[v->get_qubit()].emplace_back(v); + q2_vmap[v->get_row()].emplace_back(v); } } if (cand.empty()) { @@ -169,124 +169,6 @@ void ZXGraph::print_difference(ZXGraph* other) const { } fmt::println("<<<"); } -namespace detail { - -/** - * @brief Print the vertex with color - * - * @param v - * @return string - */ -std::string get_colored_vertex_string(ZXVertex* v) { - using namespace dvlab; - if (v->get_type() == VertexType::boundary) - return fmt::format("{}", v->get_id()); - else if (v->get_type() == VertexType::z) - return fmt::format("{}", fmt_ext::styled_if_ansi_supported(v->get_id(), fmt::fg(fmt::terminal_color::green) | fmt::emphasis::bold)); - else if (v->get_type() == VertexType::x) - return fmt::format("{}", fmt_ext::styled_if_ansi_supported(v->get_id(), fmt::fg(fmt::terminal_color::red) | fmt::emphasis::bold)); - else - return fmt::format("{}", fmt_ext::styled_if_ansi_supported(v->get_id(), fmt::fg(fmt::terminal_color::yellow) | fmt::emphasis::bold)); -} - -} // namespace detail -/** - * @brief Draw ZXGraph in CLI - * - */ -[[deprecated("Console output is too limited to draw a graph")]] void ZXGraph::draw() const { - fmt::println(""); - std::unordered_map q_pair; - QubitIdList qubit_ids; // number of qubit - - // maxCol - - auto max_col = gsl::narrow_cast(std::ranges::max(this->get_vertices() | std::views::transform([](ZXVertex* v) { return v->get_col(); }))); - - QubitIdList qubit_ids_temp; // number of qubit - for (auto& v : get_vertices()) { - qubit_ids_temp.emplace_back(v->get_qubit()); - } - std::sort(qubit_ids_temp.begin(), qubit_ids_temp.end()); - if (qubit_ids_temp.size() == 0) { - fmt::println("Empty graph!!"); - return; - } - auto offset = qubit_ids_temp[0]; - qubit_ids.emplace_back(0); - for (size_t i = 1; i < qubit_ids_temp.size(); i++) { - if (qubit_ids_temp[i - 1] == qubit_ids_temp[i]) { - continue; - } else { - qubit_ids.emplace_back(qubit_ids_temp[i] - offset); - } - } - qubit_ids_temp.clear(); - - for (size_t i = 0; i < qubit_ids.size(); i++) { - q_pair[gsl::narrow(i)] = qubit_ids[gsl::narrow(i)]; - } - std::vector tmp; - tmp.resize(qubit_ids.size()); - std::vector> col_list(max_col + 1, tmp); - - for (auto& v : get_vertices()) { - col_list[gsl::narrow_cast(v->get_col())][q_pair[v->get_qubit() - offset]] = v; - } - - std::vector max_length(max_col + 1, 0); - for (size_t i = 0; i < col_list.size(); i++) { - for (size_t j = 0; j < col_list[i].size(); j++) { - if (col_list[i][j] != nullptr) { - if (std::to_string(col_list[i][j]->get_id()).length() > max_length[i]) max_length[i] = std::to_string(col_list[i][j]->get_id()).length(); - } - } - } - size_t max_length_q = 0; - for (size_t i = 0; i < qubit_ids.size(); i++) { - auto temp = offset + i; - if (std::to_string(temp).length() > max_length_q) max_length_q = std::to_string(temp).length(); - } - - for (size_t i = 0; i < qubit_ids.size(); i++) { - // print qubit - auto temp = offset + i; - fmt::println("[{:<{}}]", temp, max_length_q); - - // print row - for (size_t j = 0; j <= max_col; j++) { - if (std::cmp_less(i, -offset)) { - if (col_list[j][i] != nullptr) { - fmt::println("({}) ", detail::get_colored_vertex_string(col_list[j][i])); - } else { - if (j == max_col) { - fmt::println(""); - } else { - fmt::println(" {}", std::string(max_length[j] + 2, ' ')); - } - } - } else if (col_list[j][i] != nullptr) { - if (j == max_col) { - fmt::println("({})", detail::get_colored_vertex_string(col_list[j][i])); - } else { - fmt::print("({})---", detail::get_colored_vertex_string(col_list[j][i])); - } - fmt::print("{}", std::string(max_length[j] - std::to_string(col_list[j][i]->get_id()).length(), ' ')); - } else { - fmt::print("---"); - fmt::print("{}", std::string(max_length[j] + 2, '-')); - } - } - fmt::println(""); - } - for (auto& a : col_list) { - a.clear(); - } - col_list.clear(); - - max_length.clear(); - qubit_ids.clear(); -} } // namespace zx diff --git a/src/zx/zxvertex.cpp b/src/zx/zxvertex.cpp index 64a2b103..73b7d9d6 100644 --- a/src/zx/zxvertex.cpp +++ b/src/zx/zxvertex.cpp @@ -5,6 +5,8 @@ Copyright [ Copyright(c) 2023 DVLab, GIEE, NTU, Taiwan ] ****************************************************************************/ +#include + #include #include #include @@ -47,7 +49,7 @@ void ZXVertex::print_vertex(spdlog::level::level_enum lvl) const { _id, fmt::format("({}, {})", type_str, _phase.get_print_string()), 11ul + ansi_token_len - 2 * (_type == VertexType::boundary ? 1 : 0), - fmt::format("({}, {})", _qubit, _col), + is_boundary() ? fmt::format("({}, {})", _qubit, _col) : fmt::format("({}, {})", _row, _col), _neighbors.size(), fmt::join(storage | std::views::transform([](NeighborPair const& nbp) { return fmt::format("({}, {})", nbp.first->get_id(), nbp.second); }), " ")); } diff --git a/tests/conversion/zx2qc/dof/extractStep.dof b/tests/conversion/zx2qc/dof/extractStep.dof index c0306819..4c10dcc2 100644 --- a/tests/conversion/zx2qc/dof/extractStep.dof +++ b/tests/conversion/zx2qc/dof/extractStep.dof @@ -7,7 +7,7 @@ zx copy 1 qcir new qcir qubit add 3 qcir -zx print -q +zx print -r extract print --frontier extract print --neighbors extract print --axels @@ -32,5 +32,5 @@ qc2zx zx adjoint zx compose 0 zx optimize --full -zx print -q +zx print -r quit -f diff --git a/tests/conversion/zx2qc/dof/extractTof2.dof b/tests/conversion/zx2qc/dof/extractTof2.dof index 8b0d5526..68181945 100644 --- a/tests/conversion/zx2qc/dof/extractTof2.dof +++ b/tests/conversion/zx2qc/dof/extractTof2.dof @@ -2,7 +2,7 @@ extract config --optimize-level 1 zx read benchmark/zx/tof3.zx zx2ts zx optimize --full -zx print -q +zx print -r logger debug zx2qc logger warn @@ -10,7 +10,7 @@ qc2zx zx adjoint zx compose 0 zx optimize --full -zx print -q +zx print -r qcir print qcir print --diagram zx test --identity diff --git a/tests/conversion/zx2qc/ref/extractStep.log b/tests/conversion/zx2qc/ref/extractStep.log index da6c0bfa..582bd494 100644 --- a/tests/conversion/zx2qc/ref/extractStep.log +++ b/tests/conversion/zx2qc/ref/extractStep.log @@ -19,7 +19,7 @@ qsyn> qcir -> #QCir: 2 -> Now focused on: QCir 1 -qsyn> zx print -q +qsyn> zx print -r ID: 15 (Z, π/4) (Qubit, Col): (-2, 5) #Neighbors: 1 (16, H) ID: 17 (Z, -π/4) (Qubit, Col): (-2, 15) #Neighbors: 1 (18, H) @@ -169,7 +169,7 @@ qsyn> zx compose 0 qsyn> zx optimize --full -qsyn> zx print -q +qsyn> zx print -r ID: 102 (Z, π/4) (Qubit, Col): (-2, 69) #Neighbors: 1 (103, H) ID: 104 (Z, -π/4) (Qubit, Col): (-2, 79) #Neighbors: 1 (105, H) diff --git a/tests/conversion/zx2qc/ref/extractTof2.log b/tests/conversion/zx2qc/ref/extractTof2.log index 47f4d151..0ade12c1 100644 --- a/tests/conversion/zx2qc/ref/extractTof2.log +++ b/tests/conversion/zx2qc/ref/extractTof2.log @@ -6,7 +6,7 @@ qsyn> zx2ts qsyn> zx optimize --full -qsyn> zx print -q +qsyn> zx print -r ID: 27 (Z, -π/4) (Qubit, Col): (-2, 3) #Neighbors: 1 (28, H) ID: 29 (Z, -π/4) (Qubit, Col): (-2, 7) #Neighbors: 1 (30, H) @@ -181,7 +181,7 @@ qsyn> zx compose 0 qsyn> zx optimize --full -qsyn> zx print -q +qsyn> zx print -r ID: 1 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (50, -) ID: 50 (●, 0) (Qubit, Col): (0, 38) #Neighbors: 1 (1, -) diff --git a/tests/conversion/zx2ts/dof/disconnected.dof b/tests/conversion/zx2ts/dof/disconnected.dof index 0743b633..be84e7b7 100644 --- a/tests/conversion/zx2ts/dof/disconnected.dof +++ b/tests/conversion/zx2ts/dof/disconnected.dof @@ -3,8 +3,8 @@ zx vertex add input 0 zx vertex add output 0 zx vertex add input 1 zx vertex add output 1 -zx vertex add z 0 0 -zx vertex add z 0 pi +zx vertex add z 0 +zx vertex add z pi zx vertex add input 2 zx vertex add output 2 zx vertex add input 3 @@ -42,10 +42,10 @@ zx vertex add output 3 zx vertex add input 4 zx vertex add output 4 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 0 zx vertex add input 5 zx vertex add output 5 diff --git a/tests/conversion/zx2ts/ref/disconnected.log b/tests/conversion/zx2ts/ref/disconnected.log index f12681d0..6c75ed39 100644 --- a/tests/conversion/zx2ts/ref/disconnected.log +++ b/tests/conversion/zx2ts/ref/disconnected.log @@ -8,9 +8,9 @@ qsyn> zx vertex add input 1 qsyn> zx vertex add output 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 pi +qsyn> zx vertex add z pi qsyn> zx vertex add input 2 @@ -207,13 +207,13 @@ qsyn> zx vertex add input 4 qsyn> zx vertex add output 4 qsyn> -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> qsyn> zx vertex add input 5 diff --git a/tests/qcir/qcir/dof/mcp.dof b/tests/qcir/qcir/dof/mcp.dof index 9552ff9a..a1ff3577 100644 --- a/tests/qcir/qcir/dof/mcp.dof +++ b/tests/qcir/qcir/dof/mcp.dof @@ -4,9 +4,9 @@ qcir print --diagram qcir print --gate 0 qc2ts qc2zx -zx print -q +zx print -r zx optimize --full -zx print -q +zx print -r zx2ts tensor equiv 0 1 qcir delete --all diff --git a/tests/qcir/qcir/dof/mcpx.dof b/tests/qcir/qcir/dof/mcpx.dof index 2824cb8b..6d36c5bb 100644 --- a/tests/qcir/qcir/dof/mcpx.dof +++ b/tests/qcir/qcir/dof/mcpx.dof @@ -4,9 +4,9 @@ qcir print --diagram qcir print --gate 0 qc2ts qc2zx -zx print -q +zx print -r zx optimize --full -zx print -q +zx print -r zx2ts tensor equiv 0 1 qcir delete --all diff --git a/tests/qcir/qcir/ref/mcp.log b/tests/qcir/qcir/ref/mcp.log index f5fe6bff..36f8682a 100644 --- a/tests/qcir/qcir/ref/mcp.log +++ b/tests/qcir/qcir/ref/mcp.log @@ -14,7 +14,7 @@ qsyn> qc2ts qsyn> qc2zx -qsyn> zx print -q +qsyn> zx print -r ID: 7 (Z, -π/6) (Qubit, Col): (-2, 2) #Neighbors: 1 (6, H) @@ -34,7 +34,7 @@ ID: 5 (Z, π/6) (Qubit, Col): (1, 2) #Neighbors: 3 (2, -) (3 qsyn> zx optimize --full -qsyn> zx print -q +qsyn> zx print -r ID: 7 (Z, -π/6) (Qubit, Col): (-2, 2) #Neighbors: 1 (6, H) diff --git a/tests/qcir/qcir/ref/mcpx.log b/tests/qcir/qcir/ref/mcpx.log index b8fdae63..ce4db5b3 100644 --- a/tests/qcir/qcir/ref/mcpx.log +++ b/tests/qcir/qcir/ref/mcpx.log @@ -14,7 +14,7 @@ qsyn> qc2ts qsyn> qc2zx -qsyn> zx print -q +qsyn> zx print -r ID: 0 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (4, -) ID: 1 (●, 0) (Qubit, Col): (0, 3) #Neighbors: 1 (4, -) @@ -28,7 +28,7 @@ ID: 5 (X, 0) (Qubit, Col): (1, 2) #Neighbors: 3 (2, -) (3, qsyn> zx optimize --full -qsyn> zx print -q +qsyn> zx print -r ID: 0 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (4, -) ID: 1 (●, 0) (Qubit, Col): (0, 3) #Neighbors: 1 (4, -) diff --git a/tests/tensor/equiv/dof/global_norm_phase.dof b/tests/tensor/equiv/dof/global_norm_phase.dof index 5a827a71..2adcbc4c 100644 --- a/tests/tensor/equiv/dof/global_norm_phase.dof +++ b/tests/tensor/equiv/dof/global_norm_phase.dof @@ -1,8 +1,8 @@ zx new zx vertex add i 0 zx vertex add o 0 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 0 2 SIMPLE zx edge add 2 3 SIMPLE zx edge add 3 1 SIMPLE diff --git a/tests/tensor/equiv/ref/global_norm_phase.log b/tests/tensor/equiv/ref/global_norm_phase.log index b504378e..f34dd4ee 100644 --- a/tests/tensor/equiv/ref/global_norm_phase.log +++ b/tests/tensor/equiv/ref/global_norm_phase.log @@ -4,9 +4,9 @@ qsyn> zx vertex add i 0 qsyn> zx vertex add o 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 0 2 SIMPLE diff --git a/tests/tensor/manip/dof/adjoint.dof b/tests/tensor/manip/dof/adjoint.dof index 6e21caad..0fe3053c 100644 --- a/tests/tensor/manip/dof/adjoint.dof +++ b/tests/tensor/manip/dof/adjoint.dof @@ -2,7 +2,7 @@ zx new zx vertex add i 0 zx vertex add o 0 zx vertex add o 1 -zx vertex add z 0 pi/2 +zx vertex add z pi/2 zx edge add 0 3 SIMPLE zx edge add 1 3 SIMPLE zx edge add 2 3 SIMPLE diff --git a/tests/tensor/manip/ref/adjoint.log b/tests/tensor/manip/ref/adjoint.log index 76d5296b..b52ec673 100644 --- a/tests/tensor/manip/ref/adjoint.log +++ b/tests/tensor/manip/ref/adjoint.log @@ -6,7 +6,7 @@ qsyn> zx vertex add o 0 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 pi/2 +qsyn> zx vertex add z pi/2 qsyn> zx edge add 0 3 SIMPLE diff --git a/tests/zx/graph/dof/print.dof b/tests/zx/graph/dof/print.dof index 05a0ef04..2b46c65a 100644 --- a/tests/zx/graph/dof/print.dof +++ b/tests/zx/graph/dof/print.dof @@ -1,7 +1,7 @@ zx read benchmark/zx/cnot.zx zx print -v 1 0 zx print -v 1 0 d 9 -zx print -q 1 2 +zx print -r 1 2 zx read benchmark/zx/cnot.zx zx print -v zx diff --git a/tests/zx/graph/ref/print.log b/tests/zx/graph/ref/print.log index 1c6d67c3..b1f3ec81 100644 --- a/tests/zx/graph/ref/print.log +++ b/tests/zx/graph/ref/print.log @@ -9,7 +9,7 @@ ID: 0 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (2, -) qsyn> Error: invalid size_t value "d" for argument "-v"!! zx print -v 1 0 d 9 -qsyn> zx print -q 1 2 +qsyn> zx print -r 1 2 ID: 1 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (3, -) ID: 3 (X, 0) (Qubit, Col): (1, 1) #Neighbors: 3 (1, -) (2, -) (5, -) diff --git a/tests/zxrules/dof/bialgebra.dof b/tests/zxrules/dof/bialgebra.dof index 206fe47a..47c26f59 100644 --- a/tests/zxrules/dof/bialgebra.dof +++ b/tests/zxrules/dof/bialgebra.dof @@ -3,12 +3,12 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add x 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add z 1 +zx vertex add x +zx vertex add z +zx vertex add x +zx vertex add x +zx vertex add z +zx vertex add z zx edge add 5 7 SIMPLE zx edge add 0 4 SIMPLE zx edge add 1 8 SIMPLE @@ -29,18 +29,18 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add x 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add z 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add x 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add z 0 +zx vertex add x +zx vertex add z +zx vertex add x +zx vertex add x +zx vertex add z +zx vertex add z +zx vertex add x +zx vertex add z +zx vertex add x +zx vertex add x +zx vertex add z +zx vertex add z zx edge add 0 4 SIMPLE zx edge add 1 14 SIMPLE zx edge add 2 6 SIMPLE @@ -68,8 +68,8 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 0 4 SIMPLE zx edge add 2 4 SIMPLE zx edge add 1 5 SIMPLE @@ -84,18 +84,18 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add x 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add z 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add x 1 -zx vertex add x 0 -zx vertex add z 0 -zx vertex add z 0 +zx vertex add x +zx vertex add z +zx vertex add x +zx vertex add x +zx vertex add z +zx vertex add z +zx vertex add x +zx vertex add z +zx vertex add x +zx vertex add x +zx vertex add z +zx vertex add z zx edge add 0 4 SIMPLE zx edge add 1 14 HADAMARD zx edge add 2 6 SIMPLE diff --git a/tests/zxrules/dof/hadamard_fusion.dof b/tests/zxrules/dof/hadamard_fusion.dof index c24426cb..85ace538 100644 --- a/tests/zxrules/dof/hadamard_fusion.dof +++ b/tests/zxrules/dof/hadamard_fusion.dof @@ -7,7 +7,7 @@ qc2zx zx print -v zx rule --hadamard-rule zx print -v -zx vertex add hbox 0 0 +zx vertex add hbox 0 zx edge add 0 4 HADAMARD zx edge add 1 4 SIMPLE zx edge remove 0 1 ALL @@ -91,8 +91,8 @@ qcir gate add z 1 qcir print --gate qc2zx zx print -v -zx vertex add hbox 0 0 -zx vertex add hbox 1 0 +zx vertex add hbox 0 +zx vertex add hbox 0 zx edge add 4 6 HADAMARD zx edge add 6 7 SIMPLE zx edge add 7 5 HADAMARD diff --git a/tests/zxrules/dof/identity_removal.dof b/tests/zxrules/dof/identity_removal.dof index 120c172f..2c023d7e 100644 --- a/tests/zxrules/dof/identity_removal.dof +++ b/tests/zxrules/dof/identity_removal.dof @@ -1,9 +1,9 @@ zx new zx vertex add input 0 zx vertex add output 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add x 0 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add x 0 zx edge add 0 2 SIMPLE zx edge add 1 2 SIMPLE zx edge add 3 2 SIMPLE @@ -19,17 +19,17 @@ zx delete --all zx new zx vertex add input 0 zx vertex add output 0 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx vertex add input 1 zx vertex add output 1 -zx vertex add z 0 0 -zx vertex add x 0 0 -zx vertex add hbox 0 0 -zx vertex add x 0 0 -zx vertex add z 0 0 -zx vertex add z 0 1.5708 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add x 0 +zx vertex add hbox 0 +zx vertex add x 0 +zx vertex add z 0 +zx vertex add z 1.5708 +zx vertex add z 0 zx edge add 0 2 SIMPLE zx edge add 2 3 SIMPLE @@ -52,14 +52,14 @@ zx delete --all zx new zx vertex add input 0 zx vertex add output 0 -zx vertex add z 0 0 -zx vertex add x 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add hbox 0 0 -zx vertex add z 0 1.5708 -zx vertex add x 0 1.5708 +zx vertex add z 0 +zx vertex add x 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add hbox 0 +zx vertex add z 1.5708 +zx vertex add x 1.5708 zx edge add 0 2 SIMPLE zx edge add 1 2 SIMPLE zx edge add 0 3 SIMPLE diff --git a/tests/zxrules/dof/pivot.dof b/tests/zxrules/dof/pivot.dof index 137945d1..b4246d4d 100644 --- a/tests/zxrules/dof/pivot.dof +++ b/tests/zxrules/dof/pivot.dof @@ -3,13 +3,13 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 4 6 HADAMARD zx edge add 5 6 HADAMARD zx edge add 6 7 HADAMARD @@ -34,12 +34,12 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 0 +zx vertex add z 0 zx edge add 4 6 HADAMARD zx edge add 5 6 HADAMARD zx edge add 6 7 HADAMARD @@ -61,25 +61,25 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 3.14159 +zx vertex add z 0 +zx vertex add z 3.14159 zx edge add 4 5 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 4 6 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 5 7 HADAMARD zx edge add 5 8 HADAMARD zx edge add 5 9 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 5 10 HADAMARD zx edge add 5 11 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 4 12 HADAMARD zx edge add 4 13 HADAMARD zx edge add 4 14 HADAMARD @@ -92,25 +92,25 @@ zx edge add 0 10 SIMPLE zx edge add 2 7 SIMPLE zx edge add 1 11 SIMPLE zx edge add 3 11 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 6 16 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 7 17 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 8 18 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 9 19 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 10 20 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 11 21 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 12 22 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 13 23 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 14 24 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 15 25 SIMPLE logger debug zx rule --pivot @@ -124,25 +124,25 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 3.14159 +zx vertex add z 0 +zx vertex add z 3.14159 zx edge add 4 5 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 4 6 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 5 7 HADAMARD zx edge add 5 8 HADAMARD zx edge add 5 9 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 5 10 HADAMARD zx edge add 5 11 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 4 12 HADAMARD zx edge add 4 13 HADAMARD zx edge add 4 14 HADAMARD @@ -151,25 +151,25 @@ zx edge add 5 12 HADAMARD zx edge add 5 13 HADAMARD zx edge add 5 14 HADAMARD zx edge add 5 15 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 16 17 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 16 18 HADAMARD -zx vertex add z 0 0.1 -zx vertex add z 0 0.1 -zx vertex add z 0 0.1 +zx vertex add z 0.1 +zx vertex add z 0.1 +zx vertex add z 0.1 zx edge add 17 19 HADAMARD zx edge add 17 20 HADAMARD zx edge add 17 21 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 17 22 HADAMARD zx edge add 17 23 HADAMARD -zx vertex add z 0 1.2 -zx vertex add z 0 1.2 -zx vertex add z 0 1.2 -zx vertex add z 0 1.2 +zx vertex add z 1.2 +zx vertex add z 1.2 +zx vertex add z 1.2 +zx vertex add z 1.2 zx edge add 4 24 HADAMARD zx edge add 4 25 HADAMARD zx edge add 4 26 HADAMARD @@ -186,45 +186,45 @@ zx edge add 17 24 HADAMARD zx edge add 17 25 HADAMARD zx edge add 17 26 HADAMARD zx edge add 17 27 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 6 28 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 7 29 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 8 30 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 9 31 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 10 32 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 11 33 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 12 34 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 13 35 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 14 36 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 15 37 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 18 38 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 19 39 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 20 40 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 21 41 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 22 42 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 23 43 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 24 44 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 25 45 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 26 46 SIMPLE -zx vertex add x 0 0 +zx vertex add x 0 zx edge add 27 47 SIMPLE zx edge add 10 18 SIMPLE zx edge add 11 18 SIMPLE @@ -260,25 +260,25 @@ zx vertex add i 0 zx vertex add o 0 zx vertex add i 1 zx vertex add o 1 -zx vertex add z 0 0 -zx vertex add z 0 3.14159 +zx vertex add z 0 +zx vertex add z 3.14159 zx edge add 4 5 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 4 6 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 5 7 HADAMARD zx edge add 5 8 HADAMARD zx edge add 5 9 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 5 10 HADAMARD zx edge add 5 11 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 4 12 HADAMARD zx edge add 4 13 HADAMARD zx edge add 4 14 HADAMARD @@ -287,25 +287,25 @@ zx edge add 5 12 HADAMARD zx edge add 5 13 HADAMARD zx edge add 5 14 HADAMARD zx edge add 5 15 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 3.14159 +zx vertex add z 0 +zx vertex add z 3.14159 zx edge add 16 17 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 16 18 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 17 19 HADAMARD zx edge add 17 20 HADAMARD zx edge add 17 21 HADAMARD -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 17 22 HADAMARD zx edge add 17 23 HADAMARD -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 -zx vertex add z 0 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 +zx vertex add z 3.14159 zx edge add 4 24 HADAMARD zx edge add 4 25 HADAMARD zx edge add 4 26 HADAMARD @@ -326,45 +326,45 @@ zx edge add 0 5 SIMPLE zx edge add 2 7 SIMPLE zx edge add 1 23 SIMPLE zx edge add 3 23 SIMPLE -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 6 28 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 7 29 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 8 30 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 9 31 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 10 32 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 11 33 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 12 34 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 13 35 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 14 36 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 15 37 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 18 38 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 19 39 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 20 40 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 21 41 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 22 42 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 23 43 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 24 44 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 25 45 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 26 46 HADAMARD -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 27 47 HADAMARD logger debug zx rule --pivot @@ -373,12 +373,12 @@ zx print -v zx2ts zx new zx vertex add i 0 -zx vertex add x 0 0 -zx vertex add x 0 0 +zx vertex add x 0 +zx vertex add x 0 zx vertex add o 0 zx vertex add i 1 -zx vertex add x 1 0 -zx vertex add x 1 0 +zx vertex add x 0 +zx vertex add x 0 zx vertex add o 1 zx edge add 0 1 SIMPLE zx edge add 2 3 SIMPLE diff --git a/tests/zxrules/dof/spider_fusion.dof b/tests/zxrules/dof/spider_fusion.dof index d60225ae..d260053b 100644 --- a/tests/zxrules/dof/spider_fusion.dof +++ b/tests/zxrules/dof/spider_fusion.dof @@ -1,8 +1,8 @@ zx new zx vertex add input 0 zx vertex add output 0 -zx vertex add z 0 0 -zx vertex add z 0 0 +zx vertex add z 0 +zx vertex add z 0 zx edge add 2 3 SIMPLE zx edge add 1 2 SIMPLE zx edge add 2 3 SIMPLE @@ -21,11 +21,11 @@ zx new zx vertex add input 0 zx vertex add input 1 zx vertex add output 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add z 0 0 -zx vertex add x 0 0 -zx vertex add x 0 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add z 0 +zx vertex add x 0 +zx vertex add x 0 zx edge add 0 3 SIMPLE zx edge add 1 3 SIMPLE zx edge add 3 4 SIMPLE @@ -48,7 +48,7 @@ zx new zx vertex add input 0 zx vertex add input 1 zx vertex add output 0 -zx vertex add z 0 0 +zx vertex add z 0 zx edge add 0 3 SIMPLE zx edge add 1 3 SIMPLE zx edge add 2 3 SIMPLE diff --git a/tests/zxrules/full_reduce/dof/rd32-v1_68.dof b/tests/zxrules/full_reduce/dof/rd32-v1_68.dof index 5dd3cad6..7d68ce09 100644 --- a/tests/zxrules/full_reduce/dof/rd32-v1_68.dof +++ b/tests/zxrules/full_reduce/dof/rd32-v1_68.dof @@ -1,8 +1,8 @@ qcir read ./benchmark/SABRE/small/rd32-v1_68.qasm qc2zx -zx print -q +zx print -r logger info zx optimize --full logger warn -zx print -q +zx print -r quit -f diff --git a/tests/zxrules/full_reduce/ref/rd32-v1_68.log b/tests/zxrules/full_reduce/ref/rd32-v1_68.log index 9d411263..6eb29f0c 100644 --- a/tests/zxrules/full_reduce/ref/rd32-v1_68.log +++ b/tests/zxrules/full_reduce/ref/rd32-v1_68.log @@ -2,7 +2,7 @@ qsyn> qcir read ./benchmark/SABRE/small/rd32-v1_68.qasm qsyn> qc2zx -qsyn> zx print -q +qsyn> zx print -r ID: 0 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (8, -) ID: 1 (●, 0) (Qubit, Col): (0, 37) #Neighbors: 1 (35, -) @@ -90,7 +90,7 @@ qsyn> zx optimize --full qsyn> logger warn -qsyn> zx print -q +qsyn> zx print -r ID: 61 (Z, -π/4) (Qubit, Col): (-2, 6) #Neighbors: 1 (62, H) ID: 67 (Z, -π/4) (Qubit, Col): (-2, 28) #Neighbors: 1 (68, H) diff --git a/tests/zxrules/ref/bialgebra.log b/tests/zxrules/ref/bialgebra.log index 4883069d..c12ecf6e 100644 --- a/tests/zxrules/ref/bialgebra.log +++ b/tests/zxrules/ref/bialgebra.log @@ -8,17 +8,17 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add x 1 +qsyn> zx vertex add x -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add z 1 +qsyn> zx vertex add z qsyn> zx edge add 5 7 SIMPLE @@ -54,9 +54,9 @@ ID: 1 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (8, -) ID: 2 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (6, -) ID: 3 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (9, -) ID: 4 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (0, -) (8, -) (9, -) -ID: 6 (X, 0) (Qubit, Col): (1, 0) #Neighbors: 3 (2, -) (8, -) (9, -) +ID: 6 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (2, -) (8, -) (9, -) ID: 8 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (1, -) (4, -) (6, -) -ID: 9 (Z, 0) (Qubit, Col): (1, 0) #Neighbors: 3 (3, -) (4, -) (6, -) +ID: 9 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (3, -) (4, -) (6, -) Total #Vertices: 8 @@ -83,29 +83,29 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add x 1 +qsyn> zx vertex add x -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add z 1 +qsyn> zx vertex add z -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add x 1 +qsyn> zx vertex add x -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add z 0 +qsyn> zx vertex add z qsyn> zx edge add 0 4 SIMPLE @@ -156,7 +156,7 @@ ID: 1 (●, 0) (Qubit, Col): (0, 0) #Neighbors: 1 (14, -) ID: 2 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (6, -) ID: 3 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (15, -) ID: 4 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (0, -) (15, -) -ID: 6 (X, 0) (Qubit, Col): (1, 0) #Neighbors: 2 (2, -) (15, -) +ID: 6 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (2, -) (15, -) ID: 13 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (14, -) (15, -) ID: 14 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (1, -) (13, -) ID: 15 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 4 (3, -) (4, -) (6, -) (13, -) @@ -186,9 +186,9 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 0 4 SIMPLE @@ -230,29 +230,29 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add x 1 +qsyn> zx vertex add x -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add z 1 +qsyn> zx vertex add z -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add x 1 +qsyn> zx vertex add x -qsyn> zx vertex add x 0 +qsyn> zx vertex add x -qsyn> zx vertex add z 0 +qsyn> zx vertex add z -qsyn> zx vertex add z 0 +qsyn> zx vertex add z qsyn> zx edge add 0 4 SIMPLE @@ -303,11 +303,11 @@ ID: 2 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (6, -) ID: 3 (●, 0) (Qubit, Col): (1, 0) #Neighbors: 1 (15, -) ID: 4 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (0, -) (5, -) ID: 5 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (4, -) (6, H) (10, -) -ID: 6 (X, 0) (Qubit, Col): (1, 0) #Neighbors: 2 (2, -) (5, H) +ID: 6 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (2, -) (5, H) ID: 8 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (10, -) (10, H) ID: 10 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 4 (5, -) (8, -) (8, H) (11, -) ID: 11 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 3 (10, -) (12, H) (13, H) -ID: 12 (X, 0) (Qubit, Col): (1, 0) #Neighbors: 2 (11, H) (15, -) +ID: 12 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (11, H) (15, -) ID: 13 (X, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (11, H) (14, -) ID: 14 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (1, H) (13, -) ID: 15 (Z, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (3, -) (12, -) diff --git a/tests/zxrules/ref/hadamard_fusion.log b/tests/zxrules/ref/hadamard_fusion.log index 16b9c269..7fab49a0 100644 --- a/tests/zxrules/ref/hadamard_fusion.log +++ b/tests/zxrules/ref/hadamard_fusion.log @@ -42,7 +42,7 @@ ID: 1 (●, 0) (Qubit, Col): (0, 3) #Neighbors: 1 (0, -) Total #Vertices: 2 -qsyn> zx vertex add hbox 0 0 +qsyn> zx vertex add hbox 0 [info] Adding vertex 4... qsyn> zx edge add 0 4 HADAMARD @@ -402,10 +402,10 @@ ID: 5 (Z, π) (Qubit, Col): (1, 1) #Neighbors: 2 (2, -) (3 Total #Vertices: 6 -qsyn> zx vertex add hbox 0 0 +qsyn> zx vertex add hbox 0 [info] Adding vertex 6... -qsyn> zx vertex add hbox 1 0 +qsyn> zx vertex add hbox 0 [info] Adding vertex 7... qsyn> zx edge add 4 6 HADAMARD @@ -426,7 +426,7 @@ ID: 3 (●, 0) (Qubit, Col): (1, 2) #Neighbors: 1 (5, -) ID: 4 (Z, π) (Qubit, Col): (0, 1) #Neighbors: 3 (0, -) (1, -) (6, H) ID: 5 (Z, π) (Qubit, Col): (1, 1) #Neighbors: 3 (2, -) (3, -) (7, H) ID: 6 (H, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (4, H) (7, -) -ID: 7 (H, 0) (Qubit, Col): (1, 0) #Neighbors: 2 (5, H) (6, -) +ID: 7 (H, 0) (Qubit, Col): (0, 0) #Neighbors: 2 (5, H) (6, -) Total #Vertices: 8 diff --git a/tests/zxrules/ref/identity_removal.log b/tests/zxrules/ref/identity_removal.log index f9ce8159..6362612e 100644 --- a/tests/zxrules/ref/identity_removal.log +++ b/tests/zxrules/ref/identity_removal.log @@ -4,11 +4,11 @@ qsyn> zx vertex add input 0 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 0 2 SIMPLE @@ -65,27 +65,27 @@ qsyn> zx vertex add input 0 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx vertex add input 1 qsyn> zx vertex add output 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add hbox 0 0 +qsyn> zx vertex add hbox 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 1.5708 +qsyn> zx vertex add z 1.5708 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> qsyn> zx edge add 0 2 SIMPLE @@ -169,21 +169,21 @@ qsyn> zx vertex add input 0 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add hbox 0 0 +qsyn> zx vertex add hbox 0 -qsyn> zx vertex add z 0 1.5708 +qsyn> zx vertex add z 1.5708 -qsyn> zx vertex add x 0 1.5708 +qsyn> zx vertex add x 1.5708 qsyn> zx edge add 0 2 SIMPLE diff --git a/tests/zxrules/ref/pivot.log b/tests/zxrules/ref/pivot.log index 824063cd..afd81f52 100644 --- a/tests/zxrules/ref/pivot.log +++ b/tests/zxrules/ref/pivot.log @@ -8,19 +8,19 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 4 6 HADAMARD @@ -98,17 +98,17 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 4 6 HADAMARD @@ -174,21 +174,21 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 5 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 4 6 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 5 7 HADAMARD @@ -196,21 +196,21 @@ qsyn> zx edge add 5 8 HADAMARD qsyn> zx edge add 5 9 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 5 10 HADAMARD qsyn> zx edge add 5 11 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 12 HADAMARD @@ -236,43 +236,43 @@ qsyn> zx edge add 1 11 SIMPLE qsyn> zx edge add 3 11 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 6 16 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 7 17 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 8 18 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 9 19 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 10 20 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 11 21 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 12 22 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 13 23 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 14 24 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 15 25 SIMPLE @@ -373,21 +373,21 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 5 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 4 6 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 5 7 HADAMARD @@ -395,21 +395,21 @@ qsyn> zx edge add 5 8 HADAMARD qsyn> zx edge add 5 9 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 5 10 HADAMARD qsyn> zx edge add 5 11 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 12 HADAMARD @@ -427,21 +427,21 @@ qsyn> zx edge add 5 14 HADAMARD qsyn> zx edge add 5 15 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 16 17 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 16 18 HADAMARD -qsyn> zx vertex add z 0 0.1 +qsyn> zx vertex add z 0.1 -qsyn> zx vertex add z 0 0.1 +qsyn> zx vertex add z 0.1 -qsyn> zx vertex add z 0 0.1 +qsyn> zx vertex add z 0.1 qsyn> zx edge add 17 19 HADAMARD @@ -449,21 +449,21 @@ qsyn> zx edge add 17 20 HADAMARD qsyn> zx edge add 17 21 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 17 22 HADAMARD qsyn> zx edge add 17 23 HADAMARD -qsyn> zx vertex add z 0 1.2 +qsyn> zx vertex add z 1.2 -qsyn> zx vertex add z 0 1.2 +qsyn> zx vertex add z 1.2 -qsyn> zx vertex add z 0 1.2 +qsyn> zx vertex add z 1.2 -qsyn> zx vertex add z 0 1.2 +qsyn> zx vertex add z 1.2 qsyn> zx edge add 4 24 HADAMARD @@ -497,83 +497,83 @@ qsyn> zx edge add 17 26 HADAMARD qsyn> zx edge add 17 27 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 6 28 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 7 29 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 8 30 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 9 31 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 10 32 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 11 33 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 12 34 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 13 35 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 14 36 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 15 37 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 18 38 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 19 39 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 20 40 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 21 41 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 22 42 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 23 43 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 24 44 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 25 45 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 26 46 SIMPLE -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 27 47 SIMPLE @@ -820,21 +820,21 @@ qsyn> zx vertex add i 1 qsyn> zx vertex add o 1 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 5 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 4 6 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 5 7 HADAMARD @@ -842,21 +842,21 @@ qsyn> zx edge add 5 8 HADAMARD qsyn> zx edge add 5 9 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 5 10 HADAMARD qsyn> zx edge add 5 11 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 12 HADAMARD @@ -874,21 +874,21 @@ qsyn> zx edge add 5 14 HADAMARD qsyn> zx edge add 5 15 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 16 17 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 16 18 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 17 19 HADAMARD @@ -896,21 +896,21 @@ qsyn> zx edge add 17 20 HADAMARD qsyn> zx edge add 17 21 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 17 22 HADAMARD qsyn> zx edge add 17 23 HADAMARD -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 -qsyn> zx vertex add z 0 3.14159 +qsyn> zx vertex add z 3.14159 qsyn> zx edge add 4 24 HADAMARD @@ -952,83 +952,83 @@ qsyn> zx edge add 1 23 SIMPLE qsyn> zx edge add 3 23 SIMPLE -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 6 28 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 7 29 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 8 30 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 9 31 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 10 32 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 11 33 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 12 34 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 13 35 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 14 36 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 15 37 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 18 38 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 19 39 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 20 40 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 21 41 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 22 42 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 23 43 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 24 44 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 25 45 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 26 46 HADAMARD -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 27 47 HADAMARD @@ -1063,17 +1063,17 @@ qsyn> zx new qsyn> zx vertex add i 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx vertex add o 0 qsyn> zx vertex add i 1 -qsyn> zx vertex add x 1 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add x 1 0 +qsyn> zx vertex add x 0 qsyn> zx vertex add o 1 diff --git a/tests/zxrules/ref/spider_fusion.log b/tests/zxrules/ref/spider_fusion.log index 89f61060..60817403 100644 --- a/tests/zxrules/ref/spider_fusion.log +++ b/tests/zxrules/ref/spider_fusion.log @@ -4,9 +4,9 @@ qsyn> zx vertex add input 0 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 2 3 SIMPLE @@ -66,15 +66,15 @@ qsyn> zx vertex add input 1 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 -qsyn> zx vertex add x 0 0 +qsyn> zx vertex add x 0 qsyn> zx edge add 0 3 SIMPLE @@ -158,7 +158,7 @@ qsyn> zx vertex add input 1 qsyn> zx vertex add output 0 -qsyn> zx vertex add z 0 0 +qsyn> zx vertex add z 0 qsyn> zx edge add 0 3 SIMPLE