Initial quantum circuit.
This commit is contained in:
parent
77ce58c612
commit
20c13c1cdf
38 changed files with 1153 additions and 14 deletions
204
plugins/quantum_computing/src/QuantumCircuitReader.cpp
Normal file
204
plugins/quantum_computing/src/QuantumCircuitReader.cpp
Normal 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)
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue