Skip to content

Commit fdd9122

Browse files
committed
WIP: [py] Make single interface for polynomials
1 parent 51f7536 commit fdd9122

File tree

7 files changed

+217
-6
lines changed

7 files changed

+217
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ catch.hpp
33
__pycache__
44
tags
55
*.bak
6+
*.pyc

symbsat-py/symbsat/poly.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ def __str__(self):
5353
def copy(self):
5454
return Poly(self)
5555

56-
@classmethod
57-
def zero(cls):
58-
return cls([])
56+
def zero(self):
57+
class_ = type(self)
58+
return class_([])
5959

60-
@classmethod
61-
def one(cls):
62-
return cls([Monom.one()])
60+
def one(self):
61+
class_ = type(self)
62+
return class_([Monom.one()])
6363

6464
def is_zero(self):
6565
return self == []
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .list import PolyList # noqa

symbsat-py/symbsat/poly_new/base.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import abc
2+
3+
4+
class Poly(metaclass=abc.ABCMeta):
5+
"""Base class for boolean polynomials."""
6+
7+
def __init__(self, *, monoms=None, var=None, monom=None):
8+
is_monoms = monoms is not None
9+
is_var = var is not None
10+
is_monom = monom is not None
11+
12+
# We want zero or one parameter
13+
if [is_monoms, is_var, is_monom].count(True) > 1:
14+
raise RuntimeError("Only one initialization parameter is allowed")
15+
16+
if is_monoms:
17+
self._init_monoms(monoms)
18+
elif is_var:
19+
self._init_var(var)
20+
elif is_monom:
21+
self._init_monom(monom)
22+
else:
23+
raise NotImplementedError
24+
25+
@abc.abstractclassmethod
26+
def make_zero(cls):
27+
raise NotImplementedError
28+
29+
@abc.abstractclassmethod
30+
def make_one(cls):
31+
raise NotImplementedError
32+
33+
@abc.abstractmethod
34+
def _init_monoms(self, monoms):
35+
raise NotImplementedError
36+
37+
@abc.abstractmethod
38+
def _init_var(self, var):
39+
raise NotImplementedError
40+
41+
@abc.abstractmethod
42+
def _init_monom(self, monom):
43+
raise NotImplementedError
44+
45+
@abc.abstractmethod
46+
def __add__(self, other):
47+
raise NotImplementedError
48+
49+
@abc.abstractmethod
50+
def __mul__(self, other):
51+
raise NotImplementedError
52+
53+
@abc.abstractmethod
54+
def __str__(self):
55+
raise NotImplementedError
56+
57+
@abc.abstractmethod
58+
def copy(self):
59+
raise NotImplementedError
60+
61+
@abc.abstractmethod
62+
def is_zero(self):
63+
raise NotImplementedError
64+
65+
@abc.abstractmethod
66+
def is_one(self):
67+
raise NotImplementedError
68+
69+
@abc.abstractmethod
70+
def lm(self):
71+
raise NotImplementedError

symbsat-py/symbsat/poly_new/list.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import collections
2+
import itertools
3+
import operator
4+
5+
from symbsat.monom import Monom
6+
7+
from .base import Poly
8+
9+
10+
class PolyList(Poly):
11+
12+
def _init_monoms(self, monoms):
13+
self._list = sorted(monoms, reverse=True)
14+
15+
def _init_var(self, var):
16+
self._list = [Monom(vars=[var])]
17+
18+
def _init_monom(self, monom):
19+
self._list = [monom]
20+
21+
@classmethod
22+
def make_zero(cls):
23+
raise NotImplementedError
24+
25+
@classmethod
26+
def make_one(cls):
27+
raise NotImplementedError
28+
29+
def __add__(self, other):
30+
# symmetric difference
31+
if isinstance(other, Monom):
32+
return PolyList(monoms=list(set(self) ^ set([other])))
33+
if isinstance(other, PolyList):
34+
return PolyList(monoms=list(set(self) ^ set(other)))
35+
return NotImplemented
36+
37+
def __mul__(self, other):
38+
if isinstance(other, Monom):
39+
if self.is_zero() or other.is_zero():
40+
return PolyList.make_zero()
41+
monoms = map(lambda m: m*other, self)
42+
elif isinstance(other, PolyList):
43+
if self.is_zero() or other.is_zero():
44+
return PolyList.make_zero()
45+
monoms = itertools.starmap(
46+
operator.mul,
47+
(itertools.product(self, other))
48+
)
49+
else:
50+
return NotImplemented
51+
52+
counter = collections.Counter(monoms)
53+
return PolyList(monoms={m for m, c in counter.items() if c % 2 != 0})
54+
55+
def __str__(self):
56+
raise NotImplementedError
57+
58+
def copy(self):
59+
raise NotImplementedError
60+
61+
def is_zero(self):
62+
raise NotImplementedError
63+
64+
def is_one(self):
65+
raise NotImplementedError
66+
67+
def lm(self):
68+
raise NotImplementedError

symbsat-py/symbsat/poly_new/zdd.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from .base import Poly
2+
3+
4+
class PolyZDD(Poly):
5+
6+
@classmethod
7+
def make_zero(cls):
8+
raise NotImplementedError
9+
10+
@classmethod
11+
def make_one(cls):
12+
raise NotImplementedError
13+
14+
def _init_monoms(self, monoms):
15+
raise NotImplementedError
16+
17+
def _init_var(self, var):
18+
raise NotImplementedError
19+
20+
def _init_monom(self, monom):
21+
raise NotImplementedError
22+
23+
def __add__(self, other):
24+
raise NotImplementedError
25+
26+
def __mul__(self, other):
27+
raise NotImplementedError
28+
29+
def __str__(self):
30+
raise NotImplementedError
31+
32+
def copy(self):
33+
raise NotImplementedError
34+
35+
def is_zero(self):
36+
raise NotImplementedError
37+
38+
def is_one(self):
39+
raise NotImplementedError
40+
41+
def lm(self):
42+
raise NotImplementedError
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import unittest
2+
3+
from symbsat.monom import Monom4 as Monom
4+
from symbsat.poly_new import PolyList
5+
6+
7+
class BaseTest(unittest.TestCase):
8+
9+
def test_init_not_implemented(self):
10+
with self.assertRaises(NotImplementedError):
11+
self.poly_type()
12+
13+
def test_init_from_monoms(self):
14+
monom_a = Monom(vars=[1])
15+
monom_b = Monom(vars=[2])
16+
self.poly_type(monoms=[monom_a, monom_b])
17+
18+
19+
class TestPolyList(BaseTest):
20+
21+
def setUp(self):
22+
self.poly_type = PolyList
23+
24+
25+
def load_tests(loader, tests, pattern):
26+
suite = unittest.TestSuite()
27+
suite.addTest(TestPolyList())
28+
return suite

0 commit comments

Comments
 (0)