From 83dfc05bcd609affda283838454b9b21464c5dc4 Mon Sep 17 00:00:00 2001 From: "Davide Gessa (dakk)" Date: Thu, 14 Mar 2024 17:09:02 +0100 Subject: [PATCH] fix qfixed type definition --- qlasskit/ast2ast.py | 12 +-------- qlasskit/ast2logic/t_arguments.py | 23 +++++++++++++++++ qlasskit/types/qfixed.py | 43 ++++++++++++------------------- test/qlassf/test_fixed.py | 10 +++---- 4 files changed, 45 insertions(+), 43 deletions(-) diff --git a/qlasskit/ast2ast.py b/qlasskit/ast2ast.py index 5a4452fa..17c64b61 100644 --- a/qlasskit/ast2ast.py +++ b/qlasskit/ast2ast.py @@ -52,7 +52,7 @@ def _replace_types_annotations(ann, arg=None): ) # Replace Qlist[T,n] with Tuple[(T,)*n] - if isinstance(ann, ast.Subscript) and ann.value.id == "Qlist": + elif isinstance(ann, ast.Subscript) and ann.value.id == "Qlist": _elts = ann.slice.elts _ituple = ast.Tuple(elts=[copy.deepcopy(_elts[0])] * _elts[1].value) @@ -61,16 +61,6 @@ def _replace_types_annotations(ann, arg=None): slice=_ituple, ) - # Replace Qfixed[TI,TF] with Tuple[(TI,TF)] - elif isinstance(ann, ast.Subscript) and ann.value.id == "Qfixed": - _elts = ann.slice.elts - _ituple = ast.Tuple(elts=[copy.deepcopy(_elts[0]), copy.deepcopy(_elts[1])]) - - ann = ast.Subscript( - value=ast.Name(id="Tuple", ctx=ast.Load()), - slice=_ituple, - ) - # Replace Qmatrix[T,n,m] with Tuple[(Tuple[(T,)*m],)*n] elif isinstance(ann, ast.Subscript) and ann.value.id == "Qmatrix": _elts = ann.slice.elts diff --git a/qlasskit/ast2logic/t_arguments.py b/qlasskit/ast2logic/t_arguments.py index b2d6da6e..76f6ad23 100644 --- a/qlasskit/ast2logic/t_arguments.py +++ b/qlasskit/ast2logic/t_arguments.py @@ -53,6 +53,29 @@ def to_name(a): ttypes_t = tuple(ttypes) return Arg(base, Tuple[ttypes_t], al) + # Qfixed + if isinstance(ann, ast.Subscript) and ann.value.id == "Qfixed": # type: ignore + al = [] + ind = 0 + + if hasattr(ann.slice, "elts"): + _elts = ann.slice.elts # type: ignore + else: + _elts = [ann.slice] + + for i in _elts: # type: ignore + if isinstance(i, ast.Name) and to_name(i) == "bool": + al.append(f"{base}.{ind}") + ttypes.append(bool) + else: + inner_arg = translate_argument(i, env, base=f"{base}.{ind}") + ttypes.append(inner_arg.ttype) + al.extend(inner_arg.bitvec) + ind += 1 + ttypes_t = tuple(ttypes) + return Arg(base, Qfixed[ttypes_t], al) + + elif isinstance(ann, ast.Tuple): al = [] ind = 0 diff --git a/qlasskit/types/qfixed.py b/qlasskit/types/qfixed.py index 9c1c5abb..77ac4767 100644 --- a/qlasskit/types/qfixed.py +++ b/qlasskit/types/qfixed.py @@ -12,40 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Any, Tuple, TypeVar +from typing import Any, Tuple, TypeVar, Generic from .qint import Qint -from .qtype import TExp +from .qtype import Qtype, TExp TI = TypeVar("TI") # integer part TF = TypeVar("TF") # fractional part -class QfixedMeta(type): - def __getitem__(cls, params): - if isinstance(params, tuple) and len(params) == 2: - TI, TF = params - if isinstance(TI, int): - bs = TI - TI = Qint - TI.BIT_SIZE = bs - - if isinstance(TF, int): - bs = TF - TF = Qint - TF.BIT_SIZE = bs - - assert issubclass(TI, Qint) - assert issubclass(TF, Qint) - - return ( - TI, - TF, - ) - - -class Qfixed(metaclass=QfixedMeta): +class Qfixed(float, Qtype, Generic[TI, TF]): + def __init__(self, value): + super().__init__() + self.value = value + @classmethod def const(cls, value: Any) -> TExp: val_s = str(value).split(".") @@ -54,4 +35,12 @@ def const(cls, value: Any) -> TExp: a = Qint._const(int(val_s[0])) b = Qint._const(int(val_s[1])) - return Tuple[a[0], b[0]], [a[1], b[1]] + return Qfixed[a[0], b[0]], [a[1], b[1]] + + + # Operations + + @classmethod + def add(cls, tleft: TExp, tright: TExp) -> TExp: + """Add two Qfixed""" + pass \ No newline at end of file diff --git a/test/qlassf/test_fixed.py b/test/qlassf/test_fixed.py index b4df6190..052ba86e 100644 --- a/test/qlassf/test_fixed.py +++ b/test/qlassf/test_fixed.py @@ -24,11 +24,11 @@ @parameterized_class(("compiler"), ENABLED_COMPILERS) class TestQlassfFixed2(unittest.TestCase): def test_fixed_const(self): - f = "def test() -> Qfixed[2, 2]:\n\treturn 0.1" + f = "def test() -> Qfixed[Qint2, Qint2]:\n\treturn 0.1" qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler) compute_and_compare_results(self, qf) - # def test_sum(self): - # f = "def test(a: Qfixed[2,2]) -> Qfixed[2, 2]:\n\treturn 0.1 + a" - # qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler) - # compute_and_compare_results(self, qf) + def test_sum_const(self): + f = "def test(a: Qfixed[2,2]) -> Qfixed[2, 2]:\n\treturn 0.1 + a" + qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler) + compute_and_compare_results(self, qf)