Skip to content

Commit

Permalink
fix tests for new boolean optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
dakk committed Nov 8, 2023
1 parent d8c0a9c commit a45a2c0
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 243 deletions.
54 changes: 3 additions & 51 deletions qlasskit/boolopt/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import Dict

from sympy import Symbol
from sympy.logic.boolalg import Boolean, simplify_logic
from sympy.logic.boolalg import Boolean, simplify_logic, to_anf

from ..ast2logic import BoolExpList

Expand All @@ -37,34 +37,6 @@ def remove_const_exps(exps: BoolExpList) -> BoolExpList:
return n_exps


# def subsitute_exps(exps: BoolExpList) -> BoolExpList:
# """Subsitute exps (replace a = ~a, a = ~a, a = ~a => a = ~a)"""
# const: Dict[Symbol, Boolean] = {}
# n_exps: BoolExpList = []
# print(exps)

# for i in range(len(exps)):
# (s, e) = exps[i]
# e = e.subs(const)
# const[s] = e

# for x in e.free_symbols:
# if x in const:
# n_exps.append((x, const[x]))
# del const[x]

# for (s,e) in const.items():
# if s == e:
# continue

# n_exps.append((s,e))

# print(n_exps)
# print()
# print()
# return n_exps


def remove_unnecessary_assigns(exps: BoolExpList) -> BoolExpList:
"""Remove exp like: __a.0 = a.0, ..., a.0 = __a.0"""
n_exps: BoolExpList = []
Expand All @@ -89,23 +61,6 @@ def should_add(s, e, n_exps2):

return n_exps

# for s, e in exps:
# n_exps2 = []
# ename = f"__{s.name}"
# n_exps.append((s, e))

# for s_, e_ in reversed(n_exps):
# if s_.name == ename:
# continue
# else:
# _replaced = e_.subs(Symbol(ename), Symbol(s.name))
# if s_ != _replaced:
# n_exps2.append((s_, _replaced))

# n_exps = n_exps2[::-1]

# return n_exps


def merge_unnecessary_assigns(exps: BoolExpList) -> BoolExpList:
"""Translate exp like: __a.0 = !a, a = __a.0 ===> a = !a"""
Expand Down Expand Up @@ -185,8 +140,5 @@ def exps_simplify(exps: BoolExpList) -> BoolExpList:
return list(map(lambda e: (e[0], simplify_logic(e[1])), exps))


# [(h, a_list.0.0 & a_list.0.1), (h, a_list.1.0 & a_list.1.1 & h),
# (h, a_list.2.0 & a_list.2.1 & h), (_ret, a_list.3.0 & a_list.3.1 & h)]
# TO
# (_ret, a_list_3_0 & a_list_3_1 & a_list_2_0 & a_list_2_1 & a_list_1_0 & a_list_1_1 &
# a_list_0_0 & a_list_0_1)
def exps_to_anf(exps: BoolExpList) -> BoolExpList:
return list(map(lambda e: (e[0], to_anf(e[1])), exps))
95 changes: 45 additions & 50 deletions test/test_qlassf_bool.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,120 +43,115 @@ def test_no_return_type(self):
def test_bool_const(self):
f = "def test(a: bool) -> bool:\n\tc=True\n\treturn c"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# self.assertEqual(len(qf.expressions[0][1], True)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], True)
compute_and_compare_results(self, qf)

def test_arg_identity(self):
ex = a
f = "def test(a: bool) -> bool:\n\treturn a"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_not_arg(self):
ex = Not(a)
f = "def test(a: bool) -> bool:\n\treturn not a"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_and(self):
ex = And(Not(a), b)
f = "def test(a: bool, b: bool) -> bool:\n\treturn not a and b"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_bool_eq(self):
f = "def test(a: bool, b: bool) -> bool:\n\treturn a == b"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
compute_and_compare_results(self, qf)

def test_bool_neq(self):
f = "def test(a: bool, b: bool) -> bool:\n\treturn a != b"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
compute_and_compare_results(self, qf)

def test_or_not(self):
ex = Or(Not(a), b)
ex = Not(And(a, Not(b)))
f = "def test(a: bool, b: bool) -> bool:\n\treturn not a or b"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_multiple_arg(self):
ex = And(a, And(Not(b), c))
f = "def test(a: bool, b: bool, c: bool) -> bool:\n\treturn a and (not b) and c"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_multiple_arg2(self):
ex = And(a, And(Not(b), Or(a, c)))
ex = And(a, Not(b))
f = "def test(a: bool, b: bool, c: bool) -> bool:\n\treturn a and (not b) and (a or c)"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_ifexp(self):
ex = ITE(a, true, false)
f = "def test(a: bool) -> bool:\n\treturn True if a else False"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_ifexp2(self):
ex = ITE(And(a, And(Not(b), c)), true, false)
f = "def test(a: bool, b: bool, c: bool) -> bool:\n\treturn True if a and (not b) and c else False"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], ex)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], ex)
compute_and_compare_results(self, qf)

def test_ifexp3(self):
exp = ITE(
And(a, And(Not(b), c)),
And(c, Not(b)),
And(a, Not(c)),
)
exp = And(a, Not(And(b, c)))
f = (
"def test(a: bool, b: bool, c: bool) -> bool:\n"
+ "\treturn (c and not b) if a and ((not b) and c) else (a and not c)"
)
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# # self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], exp)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], exp)
compute_and_compare_results(self, qf)

def test_assign(self):
f = "def test(a: bool, b: bool) -> bool:\n\tc = a and b\n\treturn c"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
print(qf.expressions)
# self.assertEqual(len(qf.expressions), 1)
# self.assertEqual(len(qf.expressions[0][0], _ret)
# # self.assertEqual(len(qf.expressions[0][1], And(a, b))
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][0], _ret)
self.assertEqual(qf.expressions[0][1], And(a, b))
compute_and_compare_results(self, qf)

def test_assign2(self):
Expand All @@ -166,9 +161,9 @@ def test_assign2(self):
+ "\treturn True if d else False"
)
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
# # self.assertEqual(len(qf.expressions[0][1], And(a, And(Not(b), c)))
# self.assertEqual(len(qf.expressions[0][0], _ret)
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][1], And(a, And(Not(b), c)))
self.assertEqual(qf.expressions[0][0], _ret)
compute_and_compare_results(self, qf)

def test_assign3(self):
Expand All @@ -181,8 +176,8 @@ def test_assign3(self):
+ "\treturn g if d and e else h"
)
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 5)
# # self.assertEqual(len(qf.expressions[-1][1], ITE(d & e, g, h))
self.assertEqual(len(qf.expressions), 1)
self.assertEqual(qf.expressions[0][1], And(b, Not(a), Not(c)))
compute_and_compare_results(self, qf)


Expand Down
18 changes: 9 additions & 9 deletions test/test_qlassf_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,30 @@ class TestQlassfBuiltinFunctions(unittest.TestCase):
def test_print_call(self):
f = "def test(a: bool) -> bool:\n\tprint(a)\n\treturn a"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions), 1)
self.assertEqual(len(qf.expressions), 1)
compute_and_compare_results(self, qf)

def test_len(self):
f = "def test(a: Tuple[bool, bool]) -> Qint2:\n\treturn len(a)"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions[0][1], False)
# self.assertEqual(len(qf.expressions[1][1], True)
self.assertEqual(qf.expressions[0][1], False)
self.assertEqual(qf.expressions[1][1], True)
compute_and_compare_results(self, qf)

def test_len2(self):
f = "def test(a: Tuple[bool, bool]) -> Qint2:\n\tc=a\n\treturn len(c)"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions[-2][1], False)
# self.assertEqual(len(qf.expressions[-1][1], True)
self.assertEqual(qf.expressions[-2][1], False)
self.assertEqual(qf.expressions[-1][1], True)
compute_and_compare_results(self, qf)

def test_len4(self):
f = "def test(a: Tuple[bool, bool, bool, bool]) -> Qint4:\n\treturn len(a)"
qf = qlassf(f, to_compile=COMPILATION_ENABLED, compiler=self.compiler)
# self.assertEqual(len(qf.expressions[0][1], False)
# self.assertEqual(len(qf.expressions[1][1], False)
# self.assertEqual(len(qf.expressions[2][1], True)
# self.assertEqual(len(qf.expressions[3][1], False)
self.assertEqual(qf.expressions[0][1], False)
self.assertEqual(qf.expressions[1][1], False)
self.assertEqual(qf.expressions[2][1], True)
self.assertEqual(qf.expressions[3][1], False)
compute_and_compare_results(self, qf)

def test_min(self):
Expand Down
Loading

0 comments on commit a45a2c0

Please sign in to comment.