├── 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 |
--------------------------------------------------------------------------------