summaryrefslogtreecommitdiffstats
path: root/src/act4e_solutions/sets_power.py
blob: 1e7ec749c01cfcaef5c4a1a2e670f678e961d8f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from typing import Any, TypeVar, Iterator, Collection, List
import itertools

from .sets_representation import MyFiniteSet
from .sets_properties import SolFiniteSetProperties

import act4e_interfaces as I

X = TypeVar("X")

C = TypeVar("C") # Type of elements of set
E = MyFiniteSet[C] # Type of sets


class MyFiniteSetOfFiniteSubsets(I.FiniteSetOfFiniteSubsets[C, E]):
    # FIXME: _set could be removed
    _set: I.FiniteSet[C]
    _subsets: List[I.FiniteSet[C]]

    def __init__(self, theset: I.FiniteSet[C], subsets: Collection[I.FiniteSet[C]]):
        self._set = theset
        self._subsets = subsets

        self.fsp = SolFiniteSetProperties()
        assert(self.fsp.is_subset(s, theset) for s in subsets)

    def size(self) -> int:
        return len(self._subsets)

    def contains(self, x: E):
        # print(f"Checking whether {x.elements()} is contained in " +
        #     str(list(map(lambda l: l.elements(), self._subsets))))

        # Heuristic filter to make it a bit faster
        same_size = lambda s: s.size() == x.size()
        for s in filter(same_size, self._subsets):
            if self.fsp.equal(x, s):
                # print("it is in there!")
                return True

        return False

    def elements(self):
        return self._subsets

    def save(self, h: I.IOHelper, x: E) -> List[E]:
        # FIXME: I don't think this is correct, same problem as in save
        return cast(I.ConcreteRepr, x)

    def load(self, h: I.IOHelper, o: I.ConcreteRepr):
        # FIXME: what the f am I supposed to do here
        return cast(E, o)

    def contents(self, e: E) -> Iterator[C]:
        return e.elements()

    def construct(self, elements: Collection[C]) -> E:
        return MyFiniteSet(elements)


class SolFiniteMakePowerSet(I.FiniteMakePowerSet):
    def powerset(self, s: I.FiniteSet[X]) -> I.FiniteSetOfFiniteSubsets[X, Any]:
        subsets = [MyFiniteSet([]), s]
        for i in range(1, s.size()):
            # generate all possible subsets with i elements
            for comb in itertools.combinations(s.elements(), i):
                subsets.append(MyFiniteSet(list(comb)))

        return MyFiniteSetOfFiniteSubsets(s, subsets)