Skip to content

Commit

Permalink
Added mypy to this repo. (#16)
Browse files Browse the repository at this point in the history
I still get an error for the `mqt.ddsim` import and do not really
understand why it is there, since `mqt.ddsim` is both listed as an
additional dependency in the `pre-commit-config.yaml` and also excluded
in the `pyproject.toml`. I would have assumed, that either of those two
options should resolve the problem:

```
error: Module "mqt" has no attribute "ddsim" 
[attr-defined]
    from mqt import ddsim
```

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Lukas Burgholzer <lukas.burgholzer@jku.at>
  • Loading branch information
3 people authored Feb 10, 2023
1 parent 923bcb3 commit a723c9a
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 82 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: mypy

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
name: Run my[py] linter
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- uses: pre-commit/action@v3.0.0
with:
extra_args: mypy --all-files
13 changes: 13 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ci:
autoupdate_commit_msg: "⬆️🪝 update pre-commit hooks"
autofix_commit_msg: "🎨 pre-commit fixes"
skip: [mypy]

repos:
# Standard hooks
Expand Down Expand Up @@ -79,3 +80,15 @@ repos:
rev: "2.4.0"
hooks:
- id: nb-clean

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.991
hooks:
- id: mypy
files: ^(src|tests|setup.py)
args: []
additional_dependencies:
- types-setuptools
- python_tsp
- networkx
- mqt.ddsim
15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,18 @@ exclude = [
]

line-length = 120

[tool.mypy]
mypy_path = "$MYPY_CONFIG_FILE_DIR/src"
files = ["src", "tests", "setup.py"]
python_version = "3.9"
strict = true
show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
explicit_package_bases = true
pretty = true

[[tool.mypy.overrides]]
module = ["qiskit.*", "matplotlib.*", "python_tsp.*", "networkx.*", "mqt.ddsim.*"]
ignore_missing_imports = true
142 changes: 93 additions & 49 deletions src/mqt/problemsolver/csp.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
from __future__ import annotations

from typing import TYPE_CHECKING, TypedDict

import numpy as np
from mqt import ddsim
from mqt.ddsim import DDSIMProvider
from qiskit import QuantumCircuit, QuantumRegister, execute

if TYPE_CHECKING:
from qiskit.circuit import Instruction


class Constraint(TypedDict, total=False):
"""
Class to store the properties of a single constraint.
"""

constraint_type: str
operand_one: str
operand_two: str
to_be_satisfied_sum: int


class CSP:
def solve(
self,
constraints: list[dict],
quantum_algorithm="Grover",
):
constraints: list[Constraint],
quantum_algorithm: str = "Grover",
) -> tuple[int, int, int, int] | bool:
"""Method to solve the problem.
Keyword arguments:
Expand Down Expand Up @@ -46,7 +62,7 @@ def print_problem(
b: str | int = "b",
c: str | int = "c",
d: str | int = "d",
):
) -> None:
"""Method to visualize the problem.
Keyword arguments:
Expand All @@ -61,7 +77,13 @@ def print_problem(
print(" ", sum_s3, " | ", c, " | ", d, " |")
print("------------------\n")

def check_inequality(self, qc: QuantumCircuit, x: tuple, y: tuple, res_anc: QuantumRegister):
def check_inequality(
self,
qc: QuantumCircuit,
x: tuple[QuantumRegister, QuantumRegister],
y: tuple[QuantumRegister, QuantumRegister],
res_anc: QuantumRegister,
) -> None:
x_low, x_high = x
y_low, y_high = y

Expand All @@ -79,7 +101,13 @@ def check_inequality(self, qc: QuantumCircuit, x: tuple, y: tuple, res_anc: Quan
qc.x(y_high)
qc.cx(x_high, y_high)

def check_equality(self, qc: QuantumCircuit, x: tuple, s: str, res_anc: QuantumRegister):
def check_equality(
self,
qc: QuantumCircuit,
x: tuple[QuantumRegister, QuantumRegister, QuantumRegister],
s: str,
res_anc: QuantumRegister,
) -> None:
x_low, x_mid, x_high = x

if s[-1] == "0":
Expand All @@ -94,13 +122,13 @@ def check_equality(self, qc: QuantumCircuit, x: tuple, s: str, res_anc: QuantumR
def add_two_numbers(
self,
qc: QuantumCircuit,
x: tuple,
y: tuple,
x: tuple[QuantumRegister, QuantumRegister],
y: tuple[QuantumRegister, QuantumRegister],
ancs: QuantumRegister,
res_anc_low: QuantumRegister,
res_anc_high: QuantumRegister,
anc_carry: QuantumRegister,
):
) -> tuple[QuantumRegister, QuantumRegister, QuantumRegister]:
x_low, x_high = x
y_low, y_high = y

Expand Down Expand Up @@ -131,8 +159,8 @@ def encode_constraints(
c: QuantumRegister,
d: QuantumRegister,
anc: QuantumRegister,
constraints: list[dict],
):
constraints: list[Constraint],
) -> tuple[QuantumCircuit, list[QuantumRegister]]:
mct_list = []

dict_variable_to_quantumregister = {
Expand All @@ -147,18 +175,19 @@ def encode_constraints(
}
anc_index = 0
for constraint in constraints:
if constraint.get("type") == "inequality":
first_qreg = dict_variable_to_quantumregister.get(constraint.get("operand_one"))
second_qreg = dict_variable_to_quantumregister.get(constraint.get("operand_two"))
if constraint.get("constraint_type") == "inequality":
first_qreg = dict_variable_to_quantumregister[constraint["operand_one"]]
second_qreg = dict_variable_to_quantumregister[constraint["operand_two"]]

self.check_inequality(qc, first_qreg, second_qreg, anc[anc_index])
mct_list.append(anc[anc_index])
qc.barrier()
anc_index += anc_needed_per_constraint.get(constraint.get("type"))
anc_index += anc_needed_per_constraint[constraint["constraint_type"]]

elif constraint.get("constraint_type") == "addition_equality":
first_qreg = dict_variable_to_quantumregister[constraint["operand_one"]]
second_qreg = dict_variable_to_quantumregister[constraint["operand_two"]]

elif constraint.get("type") == "addition_equality":
first_qreg = dict_variable_to_quantumregister.get(constraint.get("operand_one"))
second_qreg = dict_variable_to_quantumregister.get(constraint.get("operand_two"))
tmp_1 = self.add_two_numbers(
qc,
first_qreg,
Expand All @@ -172,14 +201,14 @@ def encode_constraints(
self.check_equality(
qc,
tmp_1,
bin(constraint.get("sum"))[2:].zfill(3),
bin(constraint["to_be_satisfied_sum"])[2:].zfill(3),
anc[anc_index + 5],
)
mct_list.append(anc[anc_index + 5])
qc.barrier()
anc_index += anc_needed_per_constraint.get(constraint.get("type"))
anc_index += anc_needed_per_constraint[constraint["constraint_type"]]
else:
print("Unexpected constraint type: ", constraint.get("type"))
print("Unexpected constraint type: ", constraint["constraint_type"])

return (qc, mct_list)

Expand All @@ -189,7 +218,7 @@ def create_oracle(
mct_list: list[QuantumRegister],
flag: QuantumRegister,
anc_mct: QuantumRegister,
):
) -> Instruction:
compute = qc.to_instruction()

# mark solution
Expand All @@ -202,7 +231,22 @@ def create_oracle(

return qc.to_instruction(label="oracle")

def init_qc(self):
def init_qc(
self,
) -> tuple[
QuantumCircuit,
QuantumRegister,
QuantumRegister,
QuantumRegister,
int,
int,
tuple[
tuple[QuantumRegister, QuantumRegister],
tuple[QuantumRegister, QuantumRegister],
tuple[QuantumRegister, QuantumRegister],
tuple[QuantumRegister, QuantumRegister],
],
]:
a_low = QuantumRegister(1, "a_low")
a_high = QuantumRegister(1, "a_high")
a = (a_low, a_high)
Expand Down Expand Up @@ -244,7 +288,7 @@ def create_grover(
nancilla: int,
ninputs: int,
grover_iterations: int,
):
) -> QuantumCircuit:
import numpy as np

qc = QuantumCircuit(nqubits + nancilla, ninputs)
Expand All @@ -263,8 +307,8 @@ def create_grover(

return qc

def simulate(self, qc: QuantumCircuit):
backend = ddsim.DDSIMProvider().get_backend("qasm_simulator")
def simulate(self, qc: QuantumCircuit) -> tuple[int, int, int, int] | None:
backend = DDSIMProvider().get_backend("qasm_simulator")
job = execute(qc, backend, shots=10000)
counts = job.result().get_counts(qc)

Expand All @@ -287,68 +331,68 @@ def simulate(self, qc: QuantumCircuit):
print("Simulation was unsuccessful.")
return None

def get_available_quantum_algorithms(self):
def get_available_quantum_algorithms(self) -> list[str]:
"""Method to get all available quantum algorithms in a list."""
return ["Grover"]

def get_kakuro_constraints(self, sum_s0: int, sum_s1: int, sum_s2: int, sum_s3: int):
def get_kakuro_constraints(self, sum_s0: int, sum_s1: int, sum_s2: int, sum_s3: int) -> list[Constraint]:
"""Method to get a list of constraints for the inserted sums."""
list_of_constraints = []
constraint_1 = {
"type": "addition_equality",
constraint_1: Constraint = {
"constraint_type": "addition_equality",
"operand_one": "a",
"operand_two": "c",
"sum": sum_s0,
"to_be_satisfied_sum": sum_s0,
}
list_of_constraints.append(constraint_1)

constraint_2 = {
"type": "addition_equality",
constraint_2: Constraint = {
"constraint_type": "addition_equality",
"operand_one": "b",
"operand_two": "d",
"sum": sum_s1,
"to_be_satisfied_sum": sum_s1,
}
list_of_constraints.append(constraint_2)

constraint_3 = {
"type": "addition_equality",
constraint_3: Constraint = {
"constraint_type": "addition_equality",
"operand_one": "a",
"operand_two": "b",
"sum": sum_s2,
"to_be_satisfied_sum": sum_s2,
}
list_of_constraints.append(constraint_3)

constraint_4 = {
"type": "addition_equality",
constraint_4: Constraint = {
"constraint_type": "addition_equality",
"operand_one": "c",
"operand_two": "d",
"sum": sum_s3,
"to_be_satisfied_sum": sum_s3,
}
list_of_constraints.append(constraint_4)

constraint_5 = {
"type": "inequality",
constraint_5: Constraint = {
"constraint_type": "inequality",
"operand_one": "a",
"operand_two": "c",
}
list_of_constraints.append(constraint_5)

constraint_6 = {
"type": "inequality",
constraint_6: Constraint = {
"constraint_type": "inequality",
"operand_one": "b",
"operand_two": "d",
}
list_of_constraints.append(constraint_6)

constraint_7 = {
"type": "inequality",
constraint_7: Constraint = {
"constraint_type": "inequality",
"operand_one": "a",
"operand_two": "b",
}
list_of_constraints.append(constraint_7)

constraint_8 = {
"type": "inequality",
constraint_8: Constraint = {
"constraint_type": "inequality",
"operand_one": "c",
"operand_two": "d",
}
Expand Down
Loading

0 comments on commit a723c9a

Please sign in to comment.