from typing import Any, TypeVar from .semigroups_representation import MyFiniteSemigroup, MyFiniteMonoid, MyFiniteGroup import act4e_interfaces as I A = TypeVar("A") B = TypeVar("B") class SolFiniteSemigroupMorphismsChecks(I.FiniteSemigroupMorphismsChecks): def is_semigroup_morphism(self, a: I.FiniteSemigroup[A], b: I.FiniteSemigroup[B], f: I.FiniteMap[A, B]) -> bool: # Semigroup preserves the structure # f(xy) = f(x) f(y) for all x, y in a # converse: # there is an x or a y in a such that # f(xy) neq f(x) f(y) for x in a.carrier().elements(): for y in a.carrier().elements(): inside = f(a.compose(x, y)) outside = b.compose(f(x), f(y)) if not b.carrier().equal(inside, outside): return False return True def is_monoid_morphism(self, a: I.FiniteMonoid[A], b: I.FiniteMonoid[B], f: I.FiniteMap[A, B]) -> bool: # Monoid morphism is a semigroup morphism that maps identity to identity if not self.is_semigroup_morphism(a, b, f): return False if not b.carrier().equal(b.identity(), f(a.identity())): return False return True def is_group_morphism(self, a: I.FiniteGroup[A], b: I.FiniteGroup[B], f: I.FiniteMap[A, B]) -> bool: # Group morphism preserve # f(xy) = f(x)f(y) for all x, y in a # converse is # exists x, y in a such that # f(xy) neq f(x)f(y) for x in a.carrier().elements(): for y in a.carrier().elements(): inside = f(a.compose(x, y)) outside = b.compose(f(x), f(y)) if not b.carrier().equal(inside, outside): return False return True