#include "QuantumCircuitReader.h" #include "QuantumCircuit.h" #include "Qubit.h" #include "QuantumTerminal.h" #include "BasicQuantumGates.h" #include "QuantumWire.h" #include "File.h" #include "StringUtils.h" #include "FileLogger.h" std::unique_ptr QuantumCircuitReader::read(const Path& path) { File file(path); return read(file.readText()); } std::unique_ptr QuantumCircuitReader::read(const std::string& content) { auto circuit = std::make_unique(); mWorkingCircuit = circuit.get(); std::size_t cursor = 0; for (const auto& line : StringUtils::toLines(content)) { onLine(line, cursor); cursor++; } circuit->buildWireConnections(); return circuit; } void QuantumCircuitReader::onLine(const std::string& line, std::size_t jdx) { mWorkingString.clear(); std::size_t cursor = 0; while (cursor < line.size()) { const auto c = line[cursor]; MLOG_INFO("Working char: " << std::string(1, c)); if (c == '|') { if (cursor + 1 < line.size()) { if (line[cursor + 1] == '-') { onVertialQuantumWire({ cursor, jdx }); } else if (auto ket = checkForKet(line.substr(cursor + 1, line.size() - cursor)); !ket.empty()) { onKet({ cursor, jdx }, ket); cursor += ket.size() + 1; } } else { mWorkingString += c; } } else if (c == '-') { if (cursor + 1 < line.size()) { const auto end_id = getWireEnd(line.substr(cursor, line.size() - cursor)); MLOG_INFO("Wire: " << cursor << " with length " << end_id); cursor += end_id - 1; } else { mWorkingString += c; } } else { if (cursor + 1 < line.size()) { auto gate = checkForGate(line.substr(cursor, line.size() - cursor)); onGate({ cursor, jdx }, gate); cursor += gate.size() - 1; } else { mWorkingString += c; } } cursor++; } onLineEnd(); } void QuantumCircuitReader::onLineEnd() { auto output_terminal = std::make_unique(QuantumTerminal::TerminalType::OUTPUT); auto wire = std::make_unique(mWorkingElement, output_terminal.get()); mWorkingCircuit->addQuantumWire(std::move(wire)); mWorkingCircuit->addOutputTerminal(std::move(output_terminal)); mWorkingElement = nullptr; } void QuantumCircuitReader::onGate(Location loc, const std::string value) { MLOG_INFO("Got gate: " << value); QuantumGatePtr gate; if (value == "X") { gate = std::make_unique(); } else if (value == "Z") { gate = std::make_unique(); } if (gate) { auto wire = std::make_unique(mWorkingElement, gate.get()); mWorkingCircuit->addQuantumWire(std::move(wire)); mWorkingElement = gate.get(); mWorkingCircuit->addLogicGate(std::move(gate)); } } std::string QuantumCircuitReader::checkForGate(const std::string& segment) { std::string working_string; for (const auto c : segment) { if (c == '-') { break; } working_string += c; } return working_string; } void QuantumCircuitReader::onKet(Location loc, const std::string value) { MLOG_INFO("Got input state: " << value); Qubit qubit; if (value == "1") { qubit = Qubit({ 0.0, 0.0 }, { 1.0, 0.0 }); } auto input_terminal = std::make_unique(QuantumTerminal::TerminalType::INPUT); mWorkingElement = input_terminal.get(); mWorkingCircuit->addInputTerminal(std::move(input_terminal)); } std::size_t QuantumCircuitReader::getWireEnd(const std::string& segment) { std::size_t idx = 0; for (const auto c : segment) { if (c != '-') { break; } idx++; } return idx; } std::string QuantumCircuitReader::checkForKet(const std::string& segment) { std::string working_string; bool found{ false }; for (const auto c : segment) { if (c == '>') { found = true; break; } else { working_string += c; } } if (found) { return working_string; } else { return {}; } } void QuantumCircuitReader::onVertialQuantumWire(Location loc) { }