diff options
author | Nao Pross <np@0hm.ch> | 2023-10-17 19:38:38 +0200 |
---|---|---|
committer | Nao Pross <np@0hm.ch> | 2023-10-17 19:38:38 +0200 |
commit | f1ea7f0cb60bc0313ca8a7ec1e28df21fb29312f (patch) | |
tree | be3259b377515f03efee7573a20c5c55298fa548 | |
parent | Pass TestFiniteMapRepresentation and TestFiniteMapOperations (diff) | |
download | act4e-f1ea7f0cb60bc0313ca8a7ec1e28df21fb29312f.tar.gz act4e-f1ea7f0cb60bc0313ca8a7ec1e28df21fb29312f.zip |
Pass TestFiniteRelationRepresentation, TestFiniteRelationCompose, TestFiniteRelationProperties
-rw-r--r-- | src/act4e_solutions/relations.py | 52 | ||||
-rw-r--r-- | src/act4e_solutions/relations_representation.py | 58 |
2 files changed, 102 insertions, 8 deletions
diff --git a/src/act4e_solutions/relations.py b/src/act4e_solutions/relations.py index 26f90a7..c538d4d 100644 --- a/src/act4e_solutions/relations.py +++ b/src/act4e_solutions/relations.py @@ -3,6 +3,8 @@ from typing import Any, TypeVar import act4e_interfaces as I from act4e_interfaces import FiniteRelation +from .relations_representation import MyFiniteRelation + E1 = TypeVar("E1") E2 = TypeVar("E2") E3 = TypeVar("E3") @@ -14,16 +16,46 @@ B = TypeVar("B") class SolFiniteRelationProperties(I.FiniteRelationProperties): def is_surjective(self, fr: I.FiniteRelation[Any, Any]) -> bool: - raise NotImplementedError() + # for all y in B there is an x in A s.t. x R y + # converse: there is a y in B s.t. for all x in A there is no x R y + for y in fr.target().elements(): + there_is_one = any([fr.holds(x, y) for x in fr.source().elements()]) + if not there_is_one: + return False + return True def is_defined_everywhere(self, fr: I.FiniteRelation[Any, Any]) -> bool: - raise NotImplementedError() + # for all x in A there is a y in B s.t. x R y + # converse: there is an x in A s.t. for all y in B there is no x R y + for x in fr.source().elements(): + there_is_one = any([fr.holds(x, y) for y in fr.target().elements()]) + if not there_is_one: + return False + return True def is_injective(self, fr: I.FiniteRelation[Any, Any]) -> bool: - raise NotImplementedError() + # x R y and z R y implies z = x + # converse: there is a z neq y such that x R y and z R y + image = [] + for y in fr.target().elements(): + for x in fr.source().elements(): + if fr.holds(x, y): + if y in image: + return False + image.append(y) + return True def is_single_valued(self, fr: I.FiniteRelation[Any, Any]) -> bool: - raise NotImplementedError() + # x R y and x R u imply y = u + # converse: there is an y neq u such that x R y and x R u + domain = [] + for x in fr.source().elements(): + for y in fr.target().elements(): + if fr.holds(x, y): + if x in domain: + return False + domain.append(x) + return True class SolFiniteRelationOperations(I.FiniteRelationOperations): @@ -61,4 +93,14 @@ class SolFiniteEndorelationOperations(I.FiniteEndorelationOperations): class SolFiniteRelationCompose(I.FiniteRelationCompose): def compose(self, fr1: FiniteRelation[E1, E2], fr2: FiniteRelation[E2, E3]) -> I.FiniteRelation[E1, E3]: - raise NotImplementedError() + values = [] + # Yeah O(n^3), i really should do this better + for a in fr1.source().elements(): + for b in fr1.target().elements(): + for c in fr2.target().elements(): + if fr1.holds(a, b) and fr2.holds(b, c): + values.append([a, c]) + + return MyFiniteRelation(fr1.source(), fr2.target(), values) + + diff --git a/src/act4e_solutions/relations_representation.py b/src/act4e_solutions/relations_representation.py index 69ccdf0..a7fec7f 100644 --- a/src/act4e_solutions/relations_representation.py +++ b/src/act4e_solutions/relations_representation.py @@ -1,14 +1,66 @@ -from typing import TypeVar +from typing import TypeVar, List, Tuple import act4e_interfaces as I +from .sets_representation import SolFiniteSetRepresentation A = TypeVar("A") B = TypeVar("B") +class MyFiniteRelation(I.FiniteRelation[A,B]): + _source: I.FiniteSet[A] + _target: I.FiniteSet[B] + _values: List[Tuple[A,B]] + + def __init__(self, source: I.FiniteSet[A], target: I.FiniteSet[B], values: List[Tuple[A,B]]): + self._source = source + self._target = target + self._values = values + + def source(self) -> I.FiniteSet[A]: + return self._source + + def target(self) -> I.FiniteSet[B]: + return self._target + + def holds(self, a: A, b: B) -> bool: + for v, u in self._values: + if self._source.equal(v, a) and self._target.equal(u, b): + return True + return False + class SolFiniteRelationRepresentation(I.FiniteRelationRepresentation): def load(self, h: I.IOHelper, data: I.FiniteRelation_desc) -> I.FiniteRelation[A, B]: - raise NotImplementedError() + fsr = SolFiniteSetRepresentation() + src = fsr.load(h, data["source"]) + dst = fsr.load(h, data["target"]) + values = [] + + for v in data["values"]: + a, b = src.load(h, v[0]), dst.load(h, v[1]) + + if not src.contains(a): + raise I.InvalidFormat() + + if not dst.contains(b): + raise I.InvalidFormat() + + values.append([a, b]) + + return MyFiniteRelation(src, dst, values) def save(self, h: I.IOHelper, f: I.FiniteRelation[A, B]) -> I.FiniteRelation_desc: - raise NotImplementedError() + fsr = SolFiniteSetRepresentation() + d = { + "source": fsr.save(h, f.source()), + "target": fsr.save(h, f.target()), + "values": [], + } + + for a in f.source().elements(): + for b in f.target().elements(): + if f.holds(a, b): + d["values"].append([ + f.source().save(h, a), + f.target().save(h, b)]) + return d |