diff options
Diffstat (limited to 'src/act4e_solutions')
-rw-r--r-- | src/act4e_solutions/sets_product.py | 78 |
1 files changed, 74 insertions, 4 deletions
diff --git a/src/act4e_solutions/sets_product.py b/src/act4e_solutions/sets_product.py index bdba104..19a8062 100644 --- a/src/act4e_solutions/sets_product.py +++ b/src/act4e_solutions/sets_product.py @@ -1,11 +1,81 @@ -from typing import Any, Sequence, TypeVar +from functools import reduce +from collections.abc import Iterable +from typing import Any, Sequence, TypeVar, List, Iterator, cast +from math import prod import act4e_interfaces as I -X = TypeVar("X") +C = TypeVar("C") # Type of components, "factors", are setoids +E = List[C] # Type of product, i.e. that holds components -class SolFiniteMakeSetProduct(I.FiniteMakeSetProduct): +class MyFiniteSetProduct(I.FiniteSetProduct[C, E]): + _components: E + def __init__(self, components: E): + self._components = components + + # Set behaviour + def size(self) -> int: + return prod(map(lambda c: c.size(), self._components)) + + def contains(self, x: E) -> bool: + if type(x) != type(self._components): + return False + + if len(x) != len(self._components): + return False + + for (e, s) in zip(x, self._components): + if not s.contains(e): + return False + + return True + + def elements(self) -> Iterator[E]: + def all_combinations(last, new): + return [l + [n] for l in last for n in new] + + parts = map(lambda c: list(c.elements()), self._components) + elements = reduce(all_combinations, parts, [[]]) + + return list(elements) + + def save(self, h: I.IOHelper, x: E) -> I.ConcreteRepr: + return cast(I.ConcreteRepr, x) + # raise NotImplementedError + # return {"elements": [e for e in self.elements()]} + def load(self, h: I.IOHelper, o: I.ConcreteRepr): + return cast(E, o) + # raise NotImplementedError + # if not isinstance(o, dict): + # raise I.InvalidFormat() + + # if not "elements" in o: + # raise I.InvalidFormat() + + # nsets = len(o["elements"][0]) + # components = [[] for _ in range(nsets)] + # for elements in o["elements"]: + # for c, e in zip(components, elements): + # if not e in c: + # c.append(e) + + # return MyFiniteSetProduct(components) + + # Product behaviour + def components(self) -> Sequence[I.FiniteSet[C]]: + return self._components + + def pack(self, args: Sequence[C]) -> E: + return cast(E, args) + + def unpack(self, args: E) -> Sequence[C]: + return cast(Sequence[C], args) + + +X = TypeVar("X") + +class SolFiniteMakeSetProduct(I.FiniteMakeSetProduct): def product(self, components: Sequence[I.FiniteSet[X]]) -> I.FiniteSetProduct[X, Any]: - raise NotImplementedError() # implement here + return MyFiniteSetProduct(components) |