From e81367cba9d652969e8735332b9130082171fd3e Mon Sep 17 00:00:00 2001 From: "Davide Gessa (dakk)" Date: Fri, 20 Oct 2023 12:08:45 +0200 Subject: [PATCH] subtraction --- TODO.md | 2 +- docs/source/supported.rst | 30 ++++++++++++++++++++++++++++++ examples/ex4.py | 22 +++++++++++++--------- qlasskit/ast2logic/t_expression.py | 2 ++ qlasskit/types/qint.py | 10 ++++++++++ qlasskit/types/qtype.py | 4 ++++ test/test_qlassf_int.py | 17 +++++++++++++++++ 7 files changed, 77 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 2df0937c..9231ee38 100644 --- a/TODO.md +++ b/TODO.md @@ -53,7 +53,7 @@ - [x] Int arithmetic: + - [x] Qtype: bitwise not - [x] Qtype: shift right / left -- [ ] Int: subtraction +- [x] Int: subtraction - [ ] Publish doc on github ## Month 2: diff --git a/docs/source/supported.rst b/docs/source/supported.rst index 788cf7eb..7fa0de07 100644 --- a/docs/source/supported.rst +++ b/docs/source/supported.rst @@ -102,6 +102,36 @@ Comparators a > b or b <= c +Unary Op +^^^^^^^^^ + +.. code-block:: python + + ~a + + + +Bin Op +^^^^^^^^^ + +.. code-block:: python + + a << 1 + +.. code-block:: python + + a >> 2 + +.. code-block:: python + + a + b + +.. code-block:: python + + a - b + + + Function call ^^^^^^^^^^^^^ diff --git a/examples/ex4.py b/examples/ex4.py index dc8b15b6..f0dc965d 100644 --- a/examples/ex4.py +++ b/examples/ex4.py @@ -1,21 +1,21 @@ from qiskit import QuantumCircuit -from qlasskit import Qint4, qlassf +from qlasskit import Qint2, qlassf @qlassf -def f1(n: Qint4) -> Qint4: - return n + 1 +def f1(n: Qint2, q: Qint2) -> Qint2: + return n + q @qlassf -def f2(n: Qint4) -> Qint4: - return n + 3 +def f2(n: Qint2, z: Qint2) -> Qint2: + return n + z @qlassf -def f_comp(n: Qint4) -> Qint4: - return n + 1 + 3 +def f_comp(n: Qint2, q: Qint2, z: Qint2) -> Qint2: + return n + q + z print(f_comp.expressions) @@ -25,9 +25,13 @@ def f_comp(n: Qint4) -> Qint4: print(qc.decompose().draw("text")) +print(f1.expressions, f2.expressions) gate1 = f1.gate() gate2 = f2.gate() -qc = QuantumCircuit(max(gate1.num_qubits, gate2.num_qubits)) +qc = QuantumCircuit(-2 + gate1.num_qubits + gate2.num_qubits) qc.append(gate1, list(range(gate1.num_qubits))) -qc.append(gate2, list(range(gate2.num_qubits))) +qc.barrier() +qc.append( + gate2, list(range(gate1.num_qubits - 2, gate1.num_qubits + gate2.num_qubits - 2)) +) print(qc.decompose().draw("text")) diff --git a/qlasskit/ast2logic/t_expression.py b/qlasskit/ast2logic/t_expression.py index a82351b6..cac71ed2 100644 --- a/qlasskit/ast2logic/t_expression.py +++ b/qlasskit/ast2logic/t_expression.py @@ -213,6 +213,8 @@ def unfold(v_exps, op): if isinstance(expr.op, ast.Add) and hasattr(tleft[0], "add"): return tleft[0].add(tleft, tright) + elif isinstance(expr.op, ast.Sub) and hasattr(tleft[0], "sub"): + return tleft[0].sub(tleft, tright) elif ( isinstance(expr.op, ast.LShift) and hasattr(tleft[0], "shift_left") diff --git a/qlasskit/types/qint.py b/qlasskit/types/qint.py index 5acd8e7f..2d1b87ca 100644 --- a/qlasskit/types/qint.py +++ b/qlasskit/types/qint.py @@ -31,6 +31,9 @@ def __init__(self, value): def __add__(self, b): return (self.value + b) % 2**self.BIT_SIZE + def __sub__(self, b): + return (self.value - b) % 2**self.BIT_SIZE + @classmethod def from_bool(cls, v: List[bool]): return cls(int("".join(map(lambda x: "1" if x else "0", v[::-1])), 2)) @@ -161,6 +164,13 @@ def add(cls, tleft: TExp, tright: TExp) -> TExp: return (cls if cls.BIT_SIZE > tleft[0].BIT_SIZE else tleft[0], sums) # type: ignore + @classmethod + def sub(cls, tleft: TExp, tright: TExp) -> TExp: + """Subtract two Qint""" + an = cls.bitwise_not(cls.fill(tleft)) # type: ignore + su = cls.add(an, cls.fill(tright)) # type: ignore + return cls.bitwise_not(su) # type: ignore + class Qint2(Qint): BIT_SIZE = 2 diff --git a/qlasskit/types/qtype.py b/qlasskit/types/qtype.py index d9b4d003..e6f3ffeb 100644 --- a/qlasskit/types/qtype.py +++ b/qlasskit/types/qtype.py @@ -119,3 +119,7 @@ def shift_left(v: TExp, i: int = 1) -> TExp: @staticmethod def add(tleft: TExp, tcomp: TExp) -> TExp: raise Exception("abstract") + + @staticmethod + def sub(tleft: TExp, tcomp: TExp) -> TExp: + raise Exception("abstract") diff --git a/test/test_qlassf_int.py b/test/test_qlassf_int.py index db39efc0..18d9ea1d 100644 --- a/test/test_qlassf_int.py +++ b/test/test_qlassf_int.py @@ -337,3 +337,20 @@ def test_add_const4(self): f = "def test(a: Qint2) -> Qint2: return a + 2" qf = qlassf(f, to_compile=COMPILATION_ENABLED) compute_and_compare_results(self, qf) + + +class TestQlassfIntSub(unittest.TestCase): + def test_sub_const(self): + f = "def test(a: Qint2) -> Qint2: return a - 1" + qf = qlassf(f, to_compile=COMPILATION_ENABLED) + compute_and_compare_results(self, qf) + + def test_sub_const2(self): + f = "def test(a: Qint2) -> Qint2: return a - 3" + qf = qlassf(f, to_compile=COMPILATION_ENABLED) + compute_and_compare_results(self, qf) + + def test_sub_const3(self): + f = "def test(a: Qint4) -> Qint4: return a - 8" + qf = qlassf(f, to_compile=COMPILATION_ENABLED) + compute_and_compare_results(self, qf)