def get_rights_for_left(mclan: 'P(P(M x M) x N)', left: '( M )', _checked=True) -> 'P(M x N)': """Return the multiset of the right components of all couplets in the multiclan ``mclan`` associated with the left component ``left``. :return: The :term:`right multiset` of the :term:`multiclan` ``mclan`` associated with the :term:`left component` ``left`` or `Undef()` if ``mclan`` is not a multiclan. """ if _checked: if not is_member(mclan): return _undef.make_or_raise_undef2(mclan) if left is _undef.Undef(): return _mo.Set() left = _mo.auto_convert(left) else: assert is_member_or_undef(mclan) assert _mo.is_mathobject_or_undef(left) if mclan is _undef.Undef(): return _undef.make_or_raise_undef(2) if left is _undef.Undef(): return _mo.Set() clan_itr = iter(mclan) rights = _sets.multify(_relations.get_rights_for_left(next(clan_itr), left, _checked=False)) for rel in clan_itr: rights = _multisets.add( _sets.multify(_relations.get_rights_for_left(rel, left, _checked=False)), rights, _checked=False) if not rights.is_empty: if mclan.cached_is_absolute: rights.cache_absolute(_mo.CacheStatus.IS) return rights
def get_left(rel: 'P(M x M)', right: '( M )', _checked=True) -> '( M )': r"""Return the left component of the couplet that has a right component of ``right``. In general, use with :term:`right-functional` :term:`relation`\s; that is, relations where all :term:`right component`\s appear at most once. :return: The :term:`left component` of the :term:`couplet` that has a :term:`right component` of ``right``, or `Undef()` if there is not exactly one couplet with the right component ``right`` in ``rel`` or ``rel`` is not a :term:`relation`. """ if _checked: if not is_member(rel): return _undef.make_or_raise_undef2(rel) if right is _undef.Undef(): return _undef.make_or_raise_undef(2) right = _mo.auto_convert(right) else: assert is_member_or_undef(rel) assert _mo.is_mathobject_or_undef(right) if right is _undef.Undef() or rel is _undef.Undef(): return _undef.make_or_raise_undef(2) result = None for elem in rel: assert elem.is_couplet if elem.right == right: if result is not None: return _undef.make_or_raise_undef() # Early Undef() exit if more than one found. result = elem.left if result is None: return _undef.make_or_raise_undef() # Undef() exit if none found. return result
def get_rights_for_left(rel: 'P(M x M)', left: '( M )', _checked=True) -> 'P( M )': """Return the set of the right components of all couplets in the relation ``rel`` associated with the :term:`left component` ``left``. :return: The :term:`right set` of the :term:`relation` ``rel`` associated with the :term:`left component` or `Undef()` if ``rel`` is not a :term:`relation`. """ if _checked: if not is_member(rel): return _undef.make_or_raise_undef2(rel) if left is _undef.Undef(): return _mo.Set() left = _mo.auto_convert(left) else: assert is_member_or_undef(rel) assert _mo.is_mathobject_or_undef(left) if rel is _undef.Undef(): return _undef.make_or_raise_undef(2) if left is _undef.Undef(): return _mo.Set() result = _mo.Set((elem.right for elem in rel if elem.left == left), direct_load=True) if not result.is_empty: if rel.cached_is_absolute: result.cache_absolute(_mo.CacheStatus.IS) return result
def get_rights_for_left(mclan: 'P(P(M x M) x N)', left: '( M )', _checked=True) -> 'P(M x N)': """Return the multiset of the right components of all couplets in the multiclan ``mclan`` associated with the left component ``left``. :return: The :term:`right multiset` of the :term:`multiclan` ``mclan`` associated with the :term:`left component` ``left`` or `Undef()` if ``mclan`` is not a multiclan. """ if _checked: if not is_member(mclan): return _undef.make_or_raise_undef2(mclan) if left is _undef.Undef(): return _mo.Set() left = _mo.auto_convert(left) else: assert is_member_or_undef(mclan) assert _mo.is_mathobject_or_undef(left) if mclan is _undef.Undef(): return _undef.make_or_raise_undef(2) if left is _undef.Undef(): return _mo.Set() clan_itr = iter(mclan) rights = _sets.multify( _relations.get_rights_for_left(next(clan_itr), left, _checked=False)) for rel in clan_itr: rights = _multisets.add(_sets.multify( _relations.get_rights_for_left(rel, left, _checked=False)), rights, _checked=False) if not rights.is_empty: if mclan.cached_is_absolute: rights.cache_absolute(_mo.CacheStatus.IS) return rights
def get_left(rel: 'P(M x M)', right: '( M )', _checked=True) -> '( M )': r"""Return the left component of the couplet that has a right component of ``right``. In general, use with :term:`right-functional` :term:`relation`\s; that is, relations where all :term:`right component`\s appear at most once. :return: The :term:`left component` of the :term:`couplet` that has a :term:`right component` of ``right``, or `Undef()` if there is not exactly one couplet with the right component ``right`` in ``rel`` or ``rel`` is not a :term:`relation`. """ if _checked: if not is_member(rel): return _undef.make_or_raise_undef2(rel) if right is _undef.Undef(): return _undef.make_or_raise_undef(2) right = _mo.auto_convert(right) else: assert is_member_or_undef(rel) assert _mo.is_mathobject_or_undef(right) if right is _undef.Undef() or rel is _undef.Undef(): return _undef.make_or_raise_undef(2) result = None for elem in rel: assert elem.is_couplet if elem.right == right: if result is not None: return _undef.make_or_raise_undef( ) # Early Undef() exit if more than one found. result = elem.left if result is None: return _undef.make_or_raise_undef() # Undef() exit if none found. return result