diff options
-rw-r--r-- | src/act4e_solutions/semigroups_representation.py | 114 |
1 files changed, 108 insertions, 6 deletions
diff --git a/src/act4e_solutions/semigroups_representation.py b/src/act4e_solutions/semigroups_representation.py index 4d75708..f5c2780 100644 --- a/src/act4e_solutions/semigroups_representation.py +++ b/src/act4e_solutions/semigroups_representation.py @@ -1,29 +1,131 @@ from typing import Any, TypeVar import act4e_interfaces as I +from .sets_representation import MyFiniteSet, SolFiniteSetRepresentation +from .sets_product import MyFiniteSetProduct +from .maps_representation import MyFiniteMap, SolFiniteMapRepresentation X = TypeVar("X") +class MyFiniteSemigroup(I.FiniteSemigroup[X]): + _carrier: I.FiniteSet[X] + _composition: I.FiniteMap[X, X] + + def __init__(self, s: I.FiniteSet[X], f: I.FiniteMap[X, X]): + self._carrier = s + self._composition = f + + def carrier(self) -> I.FiniteSet[X]: + return self._carrier + + def composition(self) -> I.FiniteMap[X, X]: + return self._composition + + def compose(self, a: X, b: X) -> X: + p = self._composition.source().pack([a, b]) + return self._composition(p) + + +class MyFiniteMonoid(MyFiniteSemigroup, I.FiniteMonoid[X]): + _identity: X + def __init__(self, s: I.FiniteSet[X], f: I.FiniteMap[X, X], e: X): + super().__init__(s, f) + self._identity = e + + # def compose(self, a: X, b: X) -> X: + # if self.carrier().equal(a, self._identity): + # return b + # elif self.carrier().equal(b, self._identity): + # return a + # else: + # return super().compose(a, b) + + def identity(self) -> X: + return self._identity + + +class MyFiniteGroup(MyFiniteMonoid, I.FiniteGroup[X]): + _inverse: I.FiniteMap[X, X] + def __init__(self, s: I.FiniteSet[X], f: I.FiniteMap[X, X], e: X, i: I.FiniteMap[X, X]): + super().__init__(s, f, e) + self._inverse = i + + def inverse(self, a: X): + return self._inverse(a) + class SolFiniteSemigroupRepresentation(I.FiniteSemigroupRepresentation): def load(self, h: I.IOHelper, s: I.FiniteSemigroup_desc) -> I.FiniteSemigroup[Any]: - raise NotImplementedError() + if not all(k in s.keys() for k in ["carrier", "composition"]): + raise I.InvalidFormat() + + fsr = SolFiniteSetRepresentation() + A = fsr.load(h, s["carrier"]) + + # FIXME: maybe use this? + # fmr = SolFiniteMapRepresentation() + for inp, out in s["composition"]: + if not all(A.contains(i) for i in inp): + raise I.InvalidFormat() + + if not A.contains(out): + raise I.InvalidFormat() + + p = MyFiniteSetProduct([A, A]) + f = MyFiniteMap(p, A, s["composition"]) + return MyFiniteSemigroup(A, f) def save(self, h: I.IOHelper, m: I.FiniteSemigroup[Any]) -> I.FiniteSemigroup_desc: - raise NotImplementedError() + fsr = SolFiniteSetRepresentation() + fmr = SolFiniteMapRepresentation() + + d = {"carrier": fsr.save(h, m.carrier()), + "composition": []} + + for a in m.carrier().elements(): + for b in m.carrier().elements(): + e = m.composition().source().pack([a, b]) + d["composition"].append([e, m.compose(a, b)]) + + return d class SolFiniteMonoidRepresentation(I.FiniteMonoidRepresentation): def load(self, h: I.IOHelper, s: I.FiniteMonoid_desc) -> I.FiniteMonoid[X]: - raise NotImplementedError() + fsgr = SolFiniteSemigroupRepresentation() + semi = fsgr.load(h, s) + + if not ("neutral" in s.keys()): + raise I.InvalidFormat() + + e = s["neutral"] + if not semi.carrier().contains(e): + raise I.InvalidFormat() + + return MyFiniteMonoid(semi.carrier(), semi.composition(), e) def save(self, h: I.IOHelper, m: I.FiniteMonoid[Any]) -> I.FiniteMonoid_desc: - raise NotImplementedError() + fsgr = SolFiniteSemigroupRepresentation() + d = fsgr.save(h, m) + d["neutral"] = m.identity() + return d class SolFiniteGroupRepresentation(I.FiniteGroupRepresentation): def load(self, h: I.IOHelper, s: I.FiniteGroup_desc) -> I.FiniteGroup[X]: - raise NotImplementedError() + fmor = SolFiniteMonoidRepresentation() + m = fmor.load(h, s) + + if not "inverse" in s.keys(): + raise I.InvalidFormat() + + i = MyFiniteMap(m.carrier(), m.carrier(), s["inverse"]) + return MyFiniteGroup(m.carrier(), m.composition(), m.identity(), i) def save(self, h: I.IOHelper, m: I.FiniteGroup[Any]) -> I.FiniteGroup_desc: - raise NotImplementedError() + fmor = SolFiniteMonoidRepresentation() + d = fmor.save(h, m) + d["inverse"] = [] + for c in m.carrier().elements(): + d["inverse"].append([c, m.inverse(c)]) + return d |