├── examples ├── __init__.py ├── epr.py ├── dj_constant.py └── dj_balanced.py ├── pyproject.toml ├── LICENSE ├── README.md ├── .gitignore ├── state.py └── uv.lock /examples/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Examples for qwla (Quantum computing without linear algebra). 3 | """ 4 | -------------------------------------------------------------------------------- /examples/epr.py: -------------------------------------------------------------------------------- 1 | from state import State 2 | 3 | state = State(2) 4 | state.h(0) 5 | state.cx(0, 1) 6 | print(state) 7 | -------------------------------------------------------------------------------- /examples/dj_constant.py: -------------------------------------------------------------------------------- 1 | from state import State 2 | 3 | state = State(n_qubits=2) 4 | state.h(0) 5 | state.x(1) 6 | state.h(1) 7 | ## constant oracle 8 | state.x(1) 9 | ## 10 | state.h(0) 11 | state.measure(0) 12 | -------------------------------------------------------------------------------- /examples/dj_balanced.py: -------------------------------------------------------------------------------- 1 | from state import State 2 | 3 | state = State(n_qubits=2) 4 | state.h(0) 5 | state.x(1) 6 | state.h(1) 7 | ## balanced oracle 8 | state.cx(0, 1) 9 | state.x(1) 10 | ## 11 | state.h(0) 12 | state.measure(0) 13 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "qwla" 3 | version = "0.1.0" 4 | description = "Quantum computing without linear algebra" 5 | readme = "README.md" 6 | requires-python = ">=3.12" 7 | dependencies = [ 8 | "pyfunctional>=1.5.0", 9 | "bitarray>=3.4.0", 10 | ] 11 | 12 | [build-system] 13 | requires = ["hatchling"] 14 | build-backend = "hatchling.build" 15 | 16 | [tool.hatch.build.targets.wheel] 17 | packages = ["."] 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 qqq-wisc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QWLA: Quantum computing without the linear algebra 2 | 3 |
4 | 5 |
6 | QWLA is a tiny quantum circuit simulator written in Python. 7 | The goal of QWLA, as the title suggests, is to present quantum computing without using linear algebra. 8 | Instead, QWLA represents a quantum state as a dictionary and applies operations in a functional style, using map, filter, reduce, etc. 9 | 10 | ## technical details 11 | For all technical details and an introduction to quantum computing without the linear algebra, see the [accompanying paper](https://eprint.iacr.org/2025/1091.pdf). 12 | 13 | ## structure 14 | - The `state.py` file contains the `State` class, which is a quantum state and supports a number of operations (Clifford + T). 15 | - There are example circuits in the `examples/` folder. 16 | 17 | 18 | ## usage 19 | The easiest way to use QWLA is with [uv](https://docs.astral.sh/uv/getting-started/installation/). 20 | To run an example, simply: 21 | 22 | ```bash 23 | uv run examples/epr.py 24 | ``` 25 | 26 | ## citation 27 | 28 | ``` 29 | @misc{cryptoeprint:2025/1091, 30 | author = {Aws Albarghouthi}, 31 | title = {Quantum Computing without the Linear Algebra}, 32 | howpublished = {Cryptology {ePrint} Archive, Paper 2025/1091}, 33 | year = {2025}, 34 | url = {https://eprint.iacr.org/2025/1091} 35 | } 36 | ``` 37 | 38 | 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | #.idea/ 169 | 170 | # Ruff stuff: 171 | .ruff_cache/ 172 | 173 | # PyPI configuration file 174 | .pypirc 175 | -------------------------------------------------------------------------------- /state.py: -------------------------------------------------------------------------------- 1 | """ 2 | Quantum state simulator using functional programming techniques. 3 | This module implements a quantum state class that supports various quantum gates 4 | and operations without requiring matrix algebra. 5 | """ 6 | 7 | from math import sqrt, pi 8 | from cmath import exp 9 | import random 10 | from typing import Optional 11 | from functional import seq 12 | from bitarray import frozenbitarray as bitarray 13 | from bitarray import bitarray as mut_bitarray 14 | 15 | 16 | # Helper functions for bit manipulation 17 | def set_bit(x: bitarray, i: int, v: int) -> bitarray: 18 | """Set the i-th bit of bitarray x to value v (0 or 1)""" 19 | new = mut_bitarray(x) 20 | new[i] = v 21 | return bitarray(new) 22 | 23 | 24 | def flip(x: bitarray, i: int) -> bitarray: 25 | """Flip (negate) the i-th bit of bitarray x""" 26 | mask = bitarray("0" * i + "1" + "0" * (len(x) - i - 1)) 27 | return x ^ mask 28 | 29 | 30 | class State: 31 | """ 32 | Quantum state using a dictionary-like structure mapping bitstrings to amplitudes. 33 | """ 34 | 35 | def __init__(self, n_qubits: int, n_bits: int = 0): 36 | """ 37 | Initialize a quantum state with n_qubits qubits and m_bits classical bits. 38 | 39 | Args: 40 | n_qubits: Number of qubits in the system 41 | m_bits: Number of classical bits for measurement results 42 | 43 | The state starts in 0...0 (ground state). 44 | """ 45 | assert n_qubits > 0 and n_bits >= 0 46 | 47 | self.n_qubits = n_qubits 48 | self.m_bits = n_bits 49 | self.state = seq( 50 | [ 51 | (bitarray(format(i, f"0{n_qubits}b")), 1.0 if i == 0 else 0.0) 52 | for i in range(2**n_qubits) 53 | ] 54 | ) 55 | self.cbits = [0] * n_bits 56 | 57 | def x(self, j: int): 58 | """ 59 | Apply the NOT gate to the j-th qubit. 60 | 61 | This gate flips the basis states where qubit j is present. 62 | """ 63 | print(f"-> Applying X gate to qubit {j}") 64 | self.state = self.state.smap(lambda b, a: (flip(b, j), a)) 65 | return self 66 | 67 | def cx(self, j: int, k: int): 68 | """ 69 | Apply the CX (controlled-NOT) gate with control qubit ctrl (j) and target (k) qubit trgt. 70 | """ 71 | print(f"-> Applying CX gate with control {j} and target {k}") 72 | self.state = self.state.smap(lambda b, a: (b if not b[j] else flip(b, k), a)) 73 | return self 74 | 75 | def s(self, j: int): 76 | """ 77 | Apply the S (phase) gate to the j-th qubit. 78 | """ 79 | print(f"-> Applying S gate to qubit {j}") 80 | self.state = self.state.smap(lambda b, a: (b, (1j ** b[j]) * a)) 81 | return self 82 | 83 | def t(self, j: int): 84 | """ 85 | Apply the T gate to the j-th qubit. 86 | """ 87 | print(f"-> Applying T gate to qubit {j}") 88 | phase = exp(1j * pi / 4) 89 | self.state = self.state.smap(lambda b, a: (b, (phase ** b[j]) * a)) 90 | return self 91 | 92 | def h(self, j: int): 93 | """ 94 | Apply the Hadamard gate to the j-th qubit. 95 | """ 96 | print(f"-> Applying Hadamard gate to qubit {j}") 97 | norm = 1 / sqrt(2) 98 | self.state = ( 99 | self.state.smap( 100 | lambda b, a: [ 101 | (set_bit(b, j, 0), a * norm), 102 | (set_bit(b, j, 1), a * norm * (-1 if b[j] else 1)), 103 | ] 104 | ) 105 | .flatten() 106 | .reduce_by_key(lambda x, y: x + y) 107 | ) 108 | return self 109 | 110 | def measure(self, j: int, cbit: Optional[int] = None): 111 | """ 112 | Measure the j-th qubit. 113 | 114 | Args: 115 | j: Index of qubit to measure 116 | cbit: Optional classical bit to store the measurement result 117 | 118 | Returns: 119 | The state after measurement (collapsed) 120 | """ 121 | print(f"-> Measuring qubit {j}") 122 | # compute the probability of 0 123 | prob_0 = ( 124 | self.state.filter(lambda s: not s[0][j]) 125 | .smap(lambda _, a: abs(a) ** 2) 126 | .sum() 127 | .real 128 | ) # take the real component (the imaginary component is 0) 129 | 130 | print(f"\tProbability of 0: {prob_0:.3f}") 131 | measurement = int(random.random() >= prob_0) 132 | print(f"\tMeasurement result: {measurement}") 133 | 134 | if cbit is not None: 135 | self.cbits[cbit] = int(measurement) 136 | 137 | if measurement == 0: 138 | # Collapse to 0 state 139 | self.state = self.state.smap(lambda b, a: (b, a * (not b[j]))).smap( 140 | lambda b, a: (b, a / sqrt(prob_0)) 141 | ) 142 | else: 143 | # Collapse to 1 state 144 | self.state = self.state.smap(lambda b, a: (b, a * b[j])).smap( 145 | lambda b, a: (b, a / sqrt(1.0 - prob_0)) 146 | ) 147 | return self 148 | 149 | def __str__(self): 150 | """ 151 | Return a string representation of the quantum state. 152 | 153 | Format: Each bitstring with its corresponding amplitude. 154 | """ 155 | self.state = self.state.sorted(key=lambda x: x[0].to01()) 156 | 157 | result = "Quantum state:\n" + "\n".join( 158 | [f"{b.to01()}: {a:.2f}" for b, a in self.state] 159 | ) 160 | 161 | # Add classical register values if they exist 162 | if self.m_bits > 0: 163 | result += f"\n\nClassical register: {self.cbits}" 164 | 165 | return result 166 | -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | requires-python = ">=3.12" 3 | 4 | [[package]] 5 | name = "bitarray" 6 | version = "3.4.0" 7 | source = { registry = "https://pypi.org/simple" } 8 | sdist = { url = "https://files.pythonhosted.org/packages/17/7b/148091d4696b38a0b14ce495e64736472cc04b0757cc8b5e7846a1cf78a9/bitarray-3.4.0.tar.gz", hash = "sha256:33eee090eade2c8303bfc01a9e104fea306d330035b18b5c50a04cb0cb76f08d", size = 141279 } 9 | wheels = [ 10 | { url = "https://files.pythonhosted.org/packages/df/72/cb4d7c4377110aa4825c4f2971d66a856dddda229717b965ee75a5eb1845/bitarray-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef3f2dc1a95bec2af77c8685c847d41fc0c64d7329c994b6054c54462f835401", size = 139210 }, 11 | { url = "https://files.pythonhosted.org/packages/01/74/69e2d97a9525fc06430fbc9a075fa76ce9772578e480c9cc8d3b0f041afa/bitarray-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:75df7335ed7324a1ee9002d747c36a37de42b6469601ac39fef00c6bd80a4cb4", size = 136227 }, 12 | { url = "https://files.pythonhosted.org/packages/a7/eb/fc23c954e9f67c8a7116610fd204dbfed79be98ed40221cfe668aaed13c9/bitarray-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d089a0570e2acfabac9dd40ee7bfbc36ec48ff73c9312f3e61ebf31b315d05d", size = 311845 }, 13 | { url = "https://files.pythonhosted.org/packages/51/0f/3e39f6d552bdeda7434969d53e072683297bb62abb2513ea58625408ff4c/bitarray-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:823decea26d8be2ec46000583114d050d02033f99e54e3285c0a80f31e3d7784", size = 325732 }, 14 | { url = "https://files.pythonhosted.org/packages/61/33/071d392af98a57d5539440cb60e07c1f123c181fbadf6f6789000760fd61/bitarray-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f455c100df47295ca19eb36527462fecbb2710140d92a61228df4cfdd2d7dd81", size = 319493 }, 15 | { url = "https://files.pythonhosted.org/packages/7b/a6/3f331582d8bfe6177cdc2f6a258c2fb3f074721ff0cdaf53bd706a4be6d8/bitarray-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27456e66fae5726b2b1b9bc3ee0e2f1235bf8a353dc216d2651ad0652596657", size = 311900 }, 16 | { url = "https://files.pythonhosted.org/packages/e2/d4/19f84fc297b2e8e061ce9647793ab42a74f190b09a9635151a164b1d2d2d/bitarray-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f2c1c3d1d0109b993791755f18d4b495f02744118f8f683eed982b9c8ed8687", size = 299956 }, 17 | { url = "https://files.pythonhosted.org/packages/45/f8/0f506df3ce3a0bec5600a0bbba59dbdc061e2a9d5a0aaa5b597cf199e02b/bitarray-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6e7274cdfe405c4e70a585b997d3a8c001425c03fa37d09a8e5460828a3d8bd6", size = 305007 }, 18 | { url = "https://files.pythonhosted.org/packages/e9/32/4cfd70cfaa65d2ad437007adbf462995841abf8a626ef9a5cecce824061a/bitarray-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0330f470bdb76825d760215e01f8d60ce09d4ac84434b364e27236db5657d323", size = 296128 }, 19 | { url = "https://files.pythonhosted.org/packages/1e/7a/10ca59dab291c6289ab7fc2c75453bd7a906e4b48ecaac9635ed2ed08006/bitarray-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:013ba795deb6c54fdb0e70103fc142f97746074d2f67b4b6a8f67a17f2d03f06", size = 320568 }, 20 | { url = "https://files.pythonhosted.org/packages/08/0c/382f4bfd229e29e364bff0c3c29ffc60b865c21eeeab34f96cf731e223d5/bitarray-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5c62c2ae324c486f8e8f0482d5a8635e255da5302c44e7a5df83eee7d87e28ec", size = 325182 }, 21 | { url = "https://files.pythonhosted.org/packages/43/46/688f048fa43c95ba7f53d19837e5de96bb2d7ee641441ad5db20b5702d0f/bitarray-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:722c105dd4229b91d17804a0855e8f27519ceee99d8fd4db80bf09b507d7fb60", size = 303801 }, 22 | { url = "https://files.pythonhosted.org/packages/33/8d/4bd7db2d0415acbbe2aea7887dd17c6e38f25574c8676ed38da5919f9290/bitarray-3.4.0-cp312-cp312-win32.whl", hash = "sha256:d6895389eeebf6836cfad1b301bae9e5386e3b94a21076aaf0c2dab0524af6d1", size = 132479 }, 23 | { url = "https://files.pythonhosted.org/packages/74/e4/5499298f8a50883d0524c057befbbdf699ca9a56cfb76db85fafd0177f7a/bitarray-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:0a4bb5dd53250e3c70924fd473034cb2e741027938702d9cc319646e53091dc1", size = 139440 }, 24 | { url = "https://files.pythonhosted.org/packages/e3/19/9d6c8697e16b1a868cc3331e164b8a54c118f87384b5bfc506daa40ecff7/bitarray-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b238e48844645ac397cfc67f5c8df86d640a9b33063c82ca2393a39e48b01c15", size = 139195 }, 25 | { url = "https://files.pythonhosted.org/packages/46/eb/ae718c3787d5b57f167543eb92085656ec418bf6fab3e733cab2f285b9e3/bitarray-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4292ef2a67ff6a3811e018c7e32c3ce4fb74c2f5c85257c06222895138df86f4", size = 136212 }, 26 | { url = "https://files.pythonhosted.org/packages/64/7d/a98e9838c24361ab5e510f1b3b06c03a5756b1e947d3f9f138eec614917d/bitarray-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27bb390521ba1032b95e31683fa9aed042222fca653760d5101435c2dbf28ede", size = 311738 }, 27 | { url = "https://files.pythonhosted.org/packages/e3/41/5dc90c32ac9eb50648a8a103eb788f4b68e75f90bedf2ab7da1f556dad60/bitarray-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2984abfc4e6281e703675280edbcf7618fa6983367d1fb4822b41917e2c3490", size = 325631 }, 28 | { url = "https://files.pythonhosted.org/packages/a3/96/d136b999b25522c9f679224eb782caf4444a6b0a6d6112828830a59436e8/bitarray-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae10e24915c7d84f5edb39d5385455b961c66e90a40b786cfcfba59f8399999e", size = 319420 }, 29 | { url = "https://files.pythonhosted.org/packages/f1/6b/8f7b9b40e2c6d3a281f658650076ba3bd4a993c460555d7fc83188a21cf5/bitarray-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5c10255889045479b86405dd040c58e77ccf4f63a0e6e686d341b5fd8fa32c2", size = 311742 }, 30 | { url = "https://files.pythonhosted.org/packages/5f/e4/e6b783745d43bd4ce3120213f14e3758d93d5a3cabfbc476b18a803b6aa6/bitarray-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d62db2fbf0a923ecbf5b71babc9deabd5ccea74d275bf74a5e37c050238d8f6a", size = 299863 }, 31 | { url = "https://files.pythonhosted.org/packages/d1/a2/7e70a2cee6db8bc951c4bea3b646a327c859b3072ef0ae9e1f997a09ab26/bitarray-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1babc8dba17fad7409ca1cfe6ec4b89d175070f20d2c6f97f87d1c257be4aea9", size = 304969 }, 32 | { url = "https://files.pythonhosted.org/packages/c1/30/f6c7da738d9e1a87c8329670cdbd3920849bb09fca783a2952d43643fb26/bitarray-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a7eaed4731bd84504176ba5e0af3eba7a6e66afe208d5efb6a8779b66ecd51aa", size = 296171 }, 33 | { url = "https://files.pythonhosted.org/packages/ef/e4/0e1725a53d945da593291d5f61aee840a9fccdfaadc0f0282027daff7ba3/bitarray-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d0b70cf75f82c919fe486af185895a77644ac3621ea8bd5b5a82fd21c03c843", size = 320575 }, 34 | { url = "https://files.pythonhosted.org/packages/f1/a0/ff073f39227c0089c1e0c50fab09524a0f1e02fb323dc142202e68c48c49/bitarray-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e1652bf956c8874c790fe78f0dcdc0de04d82ded81373759bfc05f427afd1ff3", size = 325140 }, 35 | { url = "https://files.pythonhosted.org/packages/c4/c1/0267051bbea0025da0f43e176df7695dff50ffe0a95edc4b826725418563/bitarray-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:49a41a724693b9f15ac965f548c2f68f6ff7b0ab36a29009d82e99f7d402888b", size = 303791 }, 36 | { url = "https://files.pythonhosted.org/packages/e5/a6/bcef1426a16195f96fd905c1be68905d9f6addc1cd900ccd23875922ad78/bitarray-3.4.0-cp313-cp313-win32.whl", hash = "sha256:d3c0db664bffeb4bb80b228ed31773ccb701da11f266f9d8a56732e083e2cab0", size = 132487 }, 37 | { url = "https://files.pythonhosted.org/packages/f3/18/b69e211181f90f8a3b4ef8c7022fcdf0ebe1ad5701b68f60382195f48f66/bitarray-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:340dd788dad07ad004b591925e4b906786aaefb6632ea9d9ac616913f3cafa4e", size = 139440 }, 38 | ] 39 | 40 | [[package]] 41 | name = "dill" 42 | version = "0.4.0" 43 | source = { registry = "https://pypi.org/simple" } 44 | sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976 } 45 | wheels = [ 46 | { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668 }, 47 | ] 48 | 49 | [[package]] 50 | name = "pyfunctional" 51 | version = "1.5.0" 52 | source = { registry = "https://pypi.org/simple" } 53 | dependencies = [ 54 | { name = "dill" }, 55 | { name = "tabulate" }, 56 | ] 57 | sdist = { url = "https://files.pythonhosted.org/packages/81/1a/091aac943deb917cc4644442a39f12b52b0c3457356bfad177fadcce7de4/pyfunctional-1.5.0.tar.gz", hash = "sha256:e184f3d7167e5822b227c95292c3557cf59edf258b1f06a08c8e82991de98769", size = 107912 } 58 | wheels = [ 59 | { url = "https://files.pythonhosted.org/packages/2d/cb/9bbf9d88d200ff3aeca9fc4b83e1906bdd1c3db202b228769d02b16a7947/pyfunctional-1.5.0-py3-none-any.whl", hash = "sha256:dfee0f4110f4167801bb12f8d497230793392f694655103b794460daefbebf2b", size = 53080 }, 60 | ] 61 | 62 | [[package]] 63 | name = "qwla" 64 | version = "0.1.0" 65 | source = { editable = "." } 66 | dependencies = [ 67 | { name = "bitarray" }, 68 | { name = "pyfunctional" }, 69 | ] 70 | 71 | [package.metadata] 72 | requires-dist = [ 73 | { name = "bitarray", specifier = ">=3.4.0" }, 74 | { name = "pyfunctional", specifier = ">=1.5.0" }, 75 | ] 76 | 77 | [[package]] 78 | name = "tabulate" 79 | version = "0.9.0" 80 | source = { registry = "https://pypi.org/simple" } 81 | sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 } 82 | wheels = [ 83 | { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, 84 | ] 85 | --------------------------------------------------------------------------------