summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2023-11-16 21:58:42 +0100
committerNao Pross <np@0hm.ch>2023-11-16 21:58:42 +0100
commitae97a52c1e4adb680d4aca553a742279f76528c9 (patch)
tree84e3705565fede23de06b185d9f4c8f9a17f5345 /src
parentPass TestSemiCategoryRepresentation (diff)
downloadact4e-ae97a52c1e4adb680d4aca553a742279f76528c9.tar.gz
act4e-ae97a52c1e4adb680d4aca553a742279f76528c9.zip
Remove unused Morph and Obj, use equations
Diffstat (limited to '')
-rw-r--r--src/act4e_solutions/semicategory_representation.py70
1 files changed, 42 insertions, 28 deletions
diff --git a/src/act4e_solutions/semicategory_representation.py b/src/act4e_solutions/semicategory_representation.py
index d6977bc..9012c4f 100644
--- a/src/act4e_solutions/semicategory_representation.py
+++ b/src/act4e_solutions/semicategory_representation.py
@@ -6,7 +6,7 @@ from act4e_interfaces import EnumerableSet
from .sets_representation import MyFiniteSet
from dataclasses import dataclass
-from functools import partial
+from functools import reduce
from itertools import product
@@ -18,22 +18,11 @@ ROD = I.RichObject[OD]
RMD = I.RichMorphism[MD]
-@dataclass(frozen=True)
-class Morph(I.RichMorphism[MD]):
- source: str
- target: str
-
-
-@dataclass(frozen=True)
-class Obj(I.RichObject[OD]):
- identity: Optional[Morph]
-
-
class MySemiCategory(Generic[OD, MD], I.SemiCategory[ROD, RMD]):
- _objects: Dict[str, Obj]
- _morphisms: Dict[int, Dict[Tuple[str, str], List[Morph]]]
+ _objects: Dict[str, ROD]
+ _morphisms: Dict[int, Dict[Tuple[str, str], List[RMD]]]
_composition: Callable[[OD, OD, OD, MD], MD]
- _equations: Dict[List[str], str]
+ _equations: Dict[str, List[str]]
def __init__(
self,
@@ -45,20 +34,20 @@ class MySemiCategory(Generic[OD, MD], I.SemiCategory[ROD, RMD]):
self._composition = composition
self._equations = equations
- def add_object(self, ob: Obj):
+ def add_object(self, ob: ROD):
self._objects[ob.label] = ob
- def add_morphism(self, mor: Morph):
- if not (mor.source, mor.target) in self._morphisms[0].keys():
- self._morphisms[0][(mor.source, mor.target)] = []
- self._morphisms[0][(mor.source, mor.target)].append(mor)
+ def add_morphism(self, source: str, target: str, mor: RMD):
+ if not (source, target) in self._morphisms[0].keys():
+ self._morphisms[0][source, target] = []
+ self._morphisms[0][(source, target)].append(mor)
def objects(self, uptolevel: Optional[int] = None) -> EnumerableSet[ROD]:
return MyFiniteSet(self._objects.values())
def hom(self, ob1: ROD, ob2: ROD, uptolevel: Optional[int] = None) -> EnumerableSet[RMD]:
def all_morphisms(source, target, lvl):
- """ return all morphisms up to level lvl """
+ """ return all morphisms up to level lvl: """
# Base case, for level zero return given morphisms
if lvl <= 0:
return self._morphisms[0].get((source, target), [])
@@ -75,12 +64,33 @@ class MySemiCategory(Generic[OD, MD], I.SemiCategory[ROD, RMD]):
# Build all possible compositions
not_id = lambda m: not m.label.startswith("id_")
for f, g in product(filter(not_id, fs), filter(not_id, gs)):
+ # Compose the morphisms
source_ob = self._objects[source]
target_ob = self._objects[target]
h = self.compose(source_ob, interm_ob, target_ob, f, g)
+ # Create entry in cache if not present
if (source, target) not in self._morphisms[lvl]:
self._morphisms[lvl][source, target] = []
+
+ # If the composition is in an equation have to replace it
+ if h.label in self._equations.keys():
+ # Find the morphisms that compose the right hand side
+ rhs_morphisms = []
+ for (s, d), mors in self._morphisms[0].items():
+ for mor, f in product(mors, self._equations[h.label]):
+ if mor.label == f:
+ rhs_morphisms.append((s, d, mor))
+
+ # Build the RHS rich morphism object
+ compose = lambda m1, m2: self.compose(m1[0], m1[1], m2[0], m1[2], m2[2])
+ _, _, rhs = reduce(compose, rhs_morphisms[1:], rhs_morphisms[0])
+
+ # Save this one instead of h
+ self._morphisms[lvl][source, target].append(rhs)
+ continue
+
+ # Save the new morphism
self._morphisms[lvl][source, target].append(h)
# Compute the union
@@ -95,7 +105,7 @@ class MySemiCategory(Generic[OD, MD], I.SemiCategory[ROD, RMD]):
def compose(self, ob1: ROD, ob2: ROD, ob3: ROD, m1: RMD, m2: RMD) -> RMD:
m3 = self._composition(ob1.obdata, ob2.obdata, ob3.obdata, m1.mordata, m2.mordata)
- return Morph(";".join((m1.label, m2.label)), m3, ob1.label, ob2.label)
+ return I.RichMorphism(";".join((m1.label, m2.label)), m3)
def identity(self, ob: ROD) -> RMD:
if not self._objects[ob.label]:
@@ -116,19 +126,23 @@ class SolSemiCategoryRepresentation(I.SemiCategoryRepresentation):
if not all(k in data.keys() for k in ["objects", "morphisms", "equations"]):
raise I.InvalidFormat()
- sc = MySemiCategory(compose, data["equations"])
+ equations = {}
+ for eq_name, eq in data["equations"].items():
+ lhs, rhs = eq.split("=")
+ equations[lhs] = rhs.split(";")
+
+ sc = MySemiCategory(compose, equations)
# Get the objects
for obname, ob in data["objects"].items():
if not "obdata" in ob.keys():
raise I.InvalidFormat()
- identity = None
if "identity" in ob.keys() and ob["identity"]:
- identity = Morph(f"id_{obname}", ob["identity"]["mordata"], obname, obname)
- sc.add_morphism(identity)
+ identity = I.RichMorphism(f"id_{obname}", ob["identity"]["mordata"])
+ sc.add_morphism(obname, obname, identity)
- sc.add_object(Obj(obname, ob["obdata"], identity))
+ sc.add_object(I.RichObject(obname, ob["obdata"]))
# Get the morphisms
for morname, mor in data["morphisms"].items():
@@ -136,6 +150,6 @@ class SolSemiCategoryRepresentation(I.SemiCategoryRepresentation):
raise I.InvalidFormat()
src, tar = mor["source"], mor["target"]
- sc.add_morphism(Morph(morname, mor["mordata"], mor["source"], mor["target"]))
+ sc.add_morphism(mor["source"], mor["target"], I.RichMorphism(morname, mor["mordata"]))
return sc