Initial quantum circuit.

This commit is contained in:
jmsgrogan 2023-01-26 11:27:35 +00:00
parent 77ce58c612
commit 20c13c1cdf
38 changed files with 1153 additions and 14 deletions

View file

@ -0,0 +1,204 @@
#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<QuantumCircuit> QuantumCircuitReader::read(const Path& path)
{
File file(path);
return read(file.readText());
}
std::unique_ptr<QuantumCircuit> QuantumCircuitReader::read(const std::string& content)
{
auto circuit = std::make_unique<QuantumCircuit>();
mWorkingCircuit = circuit.get();
std::size_t cursor = 0;
for (const auto& line : StringUtils::toLines(content))
{
onLine(line, cursor);
cursor++;
}
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>(QuantumTerminal::TerminalType::OUTPUT);
auto wire = std::make_unique<QuantumWire>(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<XQuantumGate>();
}
else if (value == "Z")
{
gate = std::make_unique<ZQuantumGate>();
}
if (gate)
{
auto wire = std::make_unique<QuantumWire>(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>(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)
{
}