From 80707770944f37ac127b6e5c3a64f07b3c767d60 Mon Sep 17 00:00:00 2001 From: "Davide Gessa (dakk)" Date: Tue, 26 Sep 2023 12:10:47 +0200 Subject: [PATCH] licensing, readme badges, tox fix --- LICENSE | 222 ++++++++++++++++++++++++++--- README.md | 5 +- qlasskit/__init__.py | 14 ++ qlasskit/ast_to_logic.py | 51 ++++--- qlasskit/exceptions.py | 19 +++ qlasskit/invertible_to_qcircuit.py | 13 ++ qlasskit/logic_to_invertible.py | 13 ++ qlasskit/passes/__init__.py | 13 ++ qlasskit/qlassf.py | 20 ++- qlasskit/synth.py | 19 ++- qlasskit/typing.py | 14 ++ qlasskit/utils.py | 18 ++- 12 files changed, 376 insertions(+), 45 deletions(-) diff --git a/LICENSE b/LICENSE index 54ba5a13..cd482d89 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,201 @@ -MIT License - -Copyright (c) 2023 Davide Gessa - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all +other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or +Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work +(an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the purposes +of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, +the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including +the original version of the Work and any modifications or additions +to that Work or Derivative Works thereof, that is intentionally +submitted to Licensor for inclusion in the Work by the copyright owner +or by an individual or Legal Entity authorized to submit on behalf of +the copyright owner. For the purposes of this definition, "submitted" +means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work, +where such license applies only to those patent claims licensable +by such Contributor that are necessarily infringed by their +Contribution(s) alone or by combination of their Contribution(s) +with the Work to which such Contribution(s) was submitted. If You +institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work +or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate +as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You +meet the following conditions: + +(a) You must give any other recipients of the Work or +Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices +stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and +attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of +the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained +within such NOTICE file, excluding those notices that do not +pertain to any part of the Derivative Works, in at least one +of the following places: within a NOTICE text file distributed +as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, +within a display generated by the Derivative Works, if and +wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and +do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside +or as an addendum to the NOTICE text from the Work, provided +that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and +may provide additional or different license terms and conditions +for use, reproduction, or distribution of Your modifications, or +for any such Derivative Works as a whole, provided Your use, +reproduction, and distribution of the Work otherwise complies with +the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index 5addaa25..48000564 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Qlasskit -[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](https://unitary.fund) +[![Unitary Fund](https://img.shields.io/badge/supported_by-Unitary_Fund-yellow.svg)](https://unitary.fund) ![CI Status](https://github.com/dakk/qlasskit/actions/workflows/ci.yaml/badge.svg) +![License: Apache 2.0](https://img.shields.io/badge/license-Apache_2.0-blue) Qlasskit is a Python library that allows quantum developers to write classical algorithms in pure Python and translate them into unitary operators (gates) for use in quantum circuits. @@ -64,4 +65,4 @@ def search(alist: List4[Int2], to_search: Int2): ## License -Read [LICENSE](LICENSE). \ No newline at end of file +Read [Apache License 2.0](LICENSE). \ No newline at end of file diff --git a/qlasskit/__init__.py b/qlasskit/__init__.py index 0b1a6bd9..759787fb 100644 --- a/qlasskit/__init__.py +++ b/qlasskit/__init__.py @@ -1,3 +1,17 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + __version__ = "0.0.1" from . import exceptions # noqa: F401 diff --git a/qlasskit/ast_to_logic.py b/qlasskit/ast_to_logic.py index 49a91c41..2f258419 100644 --- a/qlasskit/ast_to_logic.py +++ b/qlasskit/ast_to_logic.py @@ -1,12 +1,26 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import ast from typing import Dict, List, Tuple, Union from sympy import Symbol -from sympy.logic import ITE, And, Implies, Not, Or, false, simplify_logic, true +from sympy.logic import ITE, And, Not, Or, false, true from . import exceptions, utils -BoolExp = Union[Symbol, And, Or, Not, ITE, type(false), type(true)] +BoolExp = Union[Symbol, And, Or, Not, ITE, bool] Env = Dict[str, str] @@ -14,7 +28,8 @@ def translate_arguments(args) -> List[Tuple[str, str]]: """Parse an argument list""" def map_arg(arg): - to_name = lambda a: a.attr if isinstance(a, ast.Attribute) else a.id + def to_name(a): + return a.attr if isinstance(a, ast.Attribute) else a.id if isinstance(arg.annotation, ast.Subscript): al = [] @@ -23,33 +38,34 @@ def map_arg(arg): return al elif to_name(arg.annotation)[0:3] == "Int": n = int(to_name(arg.annotation)[3::]) - l = [(f"{arg.arg}.{i}", "bool") for i in range(n)] - l.append((f"{arg.arg}", n)) - return l + arg_list = [(f"{arg.arg}.{i}", "bool") for i in range(n)] + arg_list.append((f"{arg.arg}", n)) + return arg_list else: return [(arg.arg, to_name(arg.annotation))] return utils.flatten(list(map(map_arg, args))) -def translate_expression(expr: ast.Expr, env: Env) -> BoolExp: +def translate_expression(expr, env: Env) -> BoolExp: # noqa: C901 """Translate an expression""" if expr == ast.Name(): if expr.id not in env: - raise UnboundException(expr.id) + raise exceptions.UnboundException(expr.id) return Symbol(expr.id) elif expr == ast.Subscript(): sn = f"{expr.value.id}.{expr.slice.value}" if sn not in env: - raise UnboundException(sn) + raise exceptions.UnboundException(sn) return Symbol(sn) elif expr == ast.BoolOp(): - def unfold(l, op): - c_exp = lambda l: op(l[0], c_exp(l[1::])) if len(l) > 1 else l[0] - return c_exp(v_exps) + def unfold(v_exps, op): + return ( + op(v_exps[0], unfold(v_exps[1::], op)) if len(v_exps) > 1 else v_exps[0] + ) v_exps = [translate_expression(e_in, env) for e_in in expr.values] @@ -59,7 +75,7 @@ def unfold(l, op): if expr.op == Not(): return Not(translate_expression(expr.operand, env)) else: - raise ExpressionNotHandledException(expr) + raise exceptions.ExpressionNotHandledException(expr) elif expr == ast.IfExp(): # (condition) and (true_value) or (not condition) and (false_value) @@ -74,9 +90,9 @@ def unfold(l, op): ) elif expr == ast.Constant(): - if expr.value == True: + if expr.value is True: return true - elif expr.value == False: + elif expr.value is False: return false else: raise exceptions.ExpressionNotHandledException(expr) @@ -93,10 +109,11 @@ def unfold(l, op): # Set # Call # List - # op Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv + # op Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift + # | BitOr | BitXor | BitAnd | FloorDiv else: - raise ExpressionNotHandledException(expr) + raise exceptions.ExpressionNotHandledException(expr) def translate_statement(stmt, env: Env) -> Tuple[List[Tuple[str, BoolExp]], Env]: diff --git a/qlasskit/exceptions.py b/qlasskit/exceptions.py index fb82b69e..7ed1121e 100644 --- a/qlasskit/exceptions.py +++ b/qlasskit/exceptions.py @@ -1,3 +1,17 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import ast @@ -14,3 +28,8 @@ def __init__(self, message): class ExpressionNotHandledException(Exception): def __init__(self, message): super().__init__(ast.dump(message)) + + +class UnboundException(Exception): + def __init__(self, message): + super().__init__(message) diff --git a/qlasskit/invertible_to_qcircuit.py b/qlasskit/invertible_to_qcircuit.py index e69de29b..34db42e8 100644 --- a/qlasskit/invertible_to_qcircuit.py +++ b/qlasskit/invertible_to_qcircuit.py @@ -0,0 +1,13 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/qlasskit/logic_to_invertible.py b/qlasskit/logic_to_invertible.py index e69de29b..34db42e8 100644 --- a/qlasskit/logic_to_invertible.py +++ b/qlasskit/logic_to_invertible.py @@ -0,0 +1,13 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/qlasskit/passes/__init__.py b/qlasskit/passes/__init__.py index e69de29b..34db42e8 100644 --- a/qlasskit/passes/__init__.py +++ b/qlasskit/passes/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/qlasskit/qlassf.py b/qlasskit/qlassf.py index dcc7456c..9b975df3 100644 --- a/qlasskit/qlassf.py +++ b/qlasskit/qlassf.py @@ -1,3 +1,17 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import ast import inspect from typing import List @@ -33,7 +47,9 @@ def __repr__(self): def from_function(f): """Create a QlassF from a function""" - fun_ast = ast.parse(f) if type(f) == str else ast.parse(inspect.getsource(f)) + fun_ast = ( + ast.parse(f) if isinstance(f, str) else ast.parse(inspect.getsource(f)) + ) fun = fun_ast.body[0] fun_name = fun.name @@ -99,7 +115,7 @@ def bind(self, **kwargs): def f(self): """Returns the classical python function""" - return original_f + return self.original_f def qlassf(f): diff --git a/qlasskit/synth.py b/qlasskit/synth.py index 19545390..8b3ca734 100644 --- a/qlasskit/synth.py +++ b/qlasskit/synth.py @@ -1,10 +1,25 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + """ Algorithm and functions able to synthetize a boolean function to a quantum circuit """ # TODO: synthetizer should translate the boolexp to an intermediate form # with invertible boolean gates; then we can apply simplifications and ancilla optimizations # After that, we do another compilation pass that decompose invertible logic to quantum gates from sympy import Symbol -from sympy.logic import ITE, And, Implies, Not, Or, false, simplify_logic, true +from sympy.logic import And, Not, Or class SynthResult: @@ -18,7 +33,7 @@ def num_qubits(self): return len(self.qubit_map) def to_qiskit(self): - from qiskit import Aer, QuantumCircuit, execute, transpile + from qiskit import QuantumCircuit qc = QuantumCircuit(len(self.qubit_map), 0) diff --git a/qlasskit/typing.py b/qlasskit/typing.py index 41129f14..1e7f8683 100644 --- a/qlasskit/typing.py +++ b/qlasskit/typing.py @@ -1,3 +1,17 @@ +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from typing import NewType Bool = NewType("Bool", bool) diff --git a/qlasskit/utils.py b/qlasskit/utils.py index 8a9d8825..e5783ee6 100644 --- a/qlasskit/utils.py +++ b/qlasskit/utils.py @@ -1 +1,17 @@ -flatten = lambda m: [item for row in m for item in row] +# Copyright 2023 Davide Gessa + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def flatten(m): + return [item for row in m for item in row]