Skip to content

Commit

Permalink
update dcos
Browse files Browse the repository at this point in the history
  • Loading branch information
dakk committed Oct 12, 2023
1 parent e2de59c commit f5336f8
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 12 deletions.
8 changes: 4 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
- [x] Test: add qubit usage check
- [x] Parametrize qint tests over bit_size
- [x] Allow constant functions
- [ ] Doc: emphatize the compiler flow
- [ ] Doc: properly render documentation
- [ ] Fix structure and typing location
- [x] Doc: emphatize the compiler flow
- [x] Doc: properly render documentation

### Week 4: (16 Oct 23)
- [ ] Test: Optimize compute_result_of_qcircuit in order to increase MAX_Q_SIM
- [ ] Publish doc
- [ ] Fix structure and typing location
- [ ] Int arithmetic expressions (+, -, *, /)
- [ ] Function call
- [ ] Builtin functions: sum(), max(), min(), len()
Expand Down
106 changes: 106 additions & 0 deletions docs/source/howitworks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,128 @@ In order to translate python code to quantum circuit, qlasskit performs several
it starts from the python *AST* (abstract synthax tree) creating *boolean expressions* as intermediate
form. Then these boolean expressions are compiled into a *quantum circuit*.

While other existing libraries translate individual operations into quantum circuits and then
combine them, qlasskit creates a single boolean expression for every output qubit of the entire
function. This approach allows for further optimization using boolean properties.

For instance, let assume we have the following function:

.. code-block:: python
def f_comp(n: Qint4) -> bool:
return n > 3 or n == 7
If we compile the whole function to a quantum circuit, we obtain the following circuit, created by
this boolean expression `n.2 | n.3 | (n.0 & n.1 & n.2 & ~n.3)`:

.. code-block:: text
f_comp
q_0: ───░─────────────────────■─────────────────
░ │
q_1: ───░─────────────────────■─────────────────
░ │
q_2: ───░──────■──────────────■─────────────────
░ │ │
q_3: ───░──────┼────■─────────┼─────────────────
░ ┌─┴─┐ │ ┌───┐ │
q_4: ───░────┤ X ├──┼──┤ X ├──┼─────────■───────
░ └───┘┌─┴─┐├───┤ │ │
q_5: ───░─────────┤ X ├┤ X ├──■─────────■───────
░ └───┘└───┘┌─┴─┐┌───┐ │
q_6: ───░───────────────────┤ X ├┤ X ├──■───────
░ └───┘└───┘┌─┴─┐┌───┐
q_7: ───░─────────────────────────────┤ X ├┤ X ├
░ └───┘└───┘
While if we decompose the function in 3 operations `n==7`, `n>3`, `a and b`, we obtain something like
the following circuit (qubit uncomputing is disabled to show the real number of gates):

.. code-block:: text
= > |
q_0: ─░─────────────■───░───────────────────────────░──────────────────────────
░ │ ░ ░
q_1: ─░─────────────■───░───────────────────────────░──────────────────────────
░ │ ░ ░
q_2: ─░─────────────■───░───■───────────────────────░──────────────────────────
░ │ ░ │ ░
q_3: ─░───■─────────┼───░───┼────■──────────────────░──────────────────────────
░ ┌─┴─┐┌───┐ │ ░ │ │ ░
q_4: ─░─┤ X ├┤ X ├──■───░───┼────┼──────────────────░──────────────────────────
░ └───┘└───┘┌─┴─┐ ░ │ │ ░
q_5: ─░───────────┤ X ├─░───┼────┼──────────────────░───■──────────────────────
░ └───┘ ░ │ │ ░ │
q_6: ─░─────────────────░───┼────┼──────────────────░───┼──────────────────────
░ ░ ┌─┴─┐ │ ┌───┐ ░ │
q_7: ─░─────────────────░─┤ X ├──┼──┤ X ├──■────────░───┼──────────────────────
░ ░ └───┘┌─┴─┐├───┤ │ ░ │
q_8: ─░─────────────────░──────┤ X ├┤ X ├──■────────░───┼──────────────────────
░ ░ └───┘└───┘┌─┴─┐┌───┐ ░ │
q_9: ─░─────────────────░────────────────┤ X ├┤ X ├─░───┼────■─────────────────
░ ░ └───┘└───┘ ░ ┌─┴─┐ │ ┌───┐
q_10: ─░─────────────────░───────────────────────────░─┤ X ├──┼──┤ X ├──■───────
░ ░ ░ └───┘┌─┴─┐├───┤ │
q_11: ─░─────────────────░───────────────────────────░──────┤ X ├┤ X ├──■───────
░ ░ ░ └───┘└───┘┌─┴─┐┌───┐
q_12: ─░─────────────────░───────────────────────────░────────────────┤ X ├┤ X ├
░ ░ ░ └───┘└───┘
AST Traslator
-----------------
Given a python function, the `qlasskit.ast2logic` module walks its synthax tree translating all the statements /
expressions to boolean expressions.


For instance, the following function:

.. code-block:: python
def f(n: Qint4) -> bool:
return n == 3
Is translated to this boolean expression:

.. code-block:: python
_ret = n.0 & n.1 & ~n.2 & ~n.3
Compiler
------------
The boolean expressions are then being fed to the `qlasskit.compiler`` which translates boolean expressions
to invertible circuits, introducing auxiliary qubits. In this step, the compiler will automatically uncompute
auxiliary qubits in order to reduce the number of qubits needed and the circuit footprint.




Result
------

The result of the compiler is a quantum circuit represented with qlasskit `QCircuit`. This circuit
can now be exported to one of the supported framework.


The previous example function `f`, is translated to the following quantum circuit:


.. code-block:: text
q_0: ─────────────────■──
q_1: ─────────────────■──
q_2: ──■──────────────┼──
│ │
q_3: ──┼────■─────────┼──
┌─┴─┐ │ ┌───┐ │
q_4: ┤ X ├──┼──┤ X ├──■──
└───┘┌─┴─┐├───┤ │
q_5: ─────┤ X ├┤ X ├──■──
└───┘└───┘┌─┴─┐
q_6: ───────────────┤ X ├
└───┘
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Qlasskit is a Python library that allows quantum developers to write classical a
Python and translate them into unitary operators (gates) for use in quantum circuits.



.. :doc:`howitworks`
.. How qlasskit internally works
Expand Down
43 changes: 35 additions & 8 deletions examples/ex1.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
from qiskit import QuantumCircuit

from qlasskit import Int4, qlassf
from qlasskit import Qint4, qlassf


@qlassf
def f(n: Int4) -> bool:
if n == 3:
return True
else:
return False
def f1(n: Qint4) -> bool:
return n == 7

@qlassf
def f2(n: Qint4, b: bool) -> bool:
return n > 3

@qlassf
def f3(a: bool, b: bool) -> bool:
return a or b

@qlassf
def f_comp(n: Qint4) -> bool:
return n > 3 or n == 7


print(f_comp.expressions)
gate = f_comp.gate()
qc = QuantumCircuit(gate.num_qubits)
qc.barrier(label="f_comp")
qc.append(gate, list(range(gate.num_qubits)))
print(qc.decompose().draw('text'))



qc = QuantumCircuit(f.num_qubits)
qc.append(f.gate(), f.qubits(0))
gate1 = f1.gate()
gate2 = f2.gate()
gate3 = f3.gate()
qc = QuantumCircuit(max(gate1.num_qubits, gate2.num_qubits) + gate3.num_qubits)
qc.barrier(label="=")
qc.append(gate1, [0, 1, 2, 3, 4, 5])
qc.barrier(label=">")
qc.append(gate2, [0, 1, 2, 3, 6, 7, 8, 9])
qc.barrier(label="|")
qc.append(gate3, [5, 9, 10, 11, 12])
print(qc.decompose().draw('text'))
32 changes: 32 additions & 0 deletions examples/ex4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from qiskit import QuantumCircuit

from qlasskit import Qint4, qlassf


@qlassf
def f1(n: Qint4) -> Qint4:
return n + 1

@qlassf
def f2(n: Qint4) -> Qint4:
return n + 3

@qlassf
def f_comp(n: Qint4) -> Qint4:
return n + 1 + 3


print(f_comp.expressions)
gate = f_comp.gate()
qc = QuantumCircuit(gate.num_qubits)
qc.append(gate, list(range(gate.num_qubits)))
print(qc.decompose().draw('text'))



gate1 = f1.gate()
gate2 = f2.gate()
qc = QuantumCircuit(max(gate1.num_qubits, gate2.num_qubits))
qc.append(gate1, list(range(gate1.num_qubits)))
qc.append(gate2, list(range(gate2.num_qubits)))
print(qc.decompose().draw('text'))
5 changes: 5 additions & 0 deletions test/test_qlassf_int.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ def test_ite_return_qint(self):
self.assertEqual(qf.expressions[1][1], ITE(a, Symbol("b.1"), Symbol("c.1")))
compute_and_compare_results(self, qf)

def test_composed_comparators(self):
f = "def f_comp(n: Qint4) -> bool: return n > 3 or n == 7"
qf = qlassf(f, to_compile=COMPILATION_ENABLED)
compute_and_compare_results(self, qf)

# def test(a: Qint2) -> Qint2:
# return a + 1
# def test(a: Qint2, b: Qint2) -> Qint2:
Expand Down

0 comments on commit f5336f8

Please sign in to comment.