def transpose(clan: 'PP(M x M)', _checked=True) -> 'PP(M x M)': """Return a clan where all relations have their left and right components swapped. :return: The :term:`unary extension` of :term:`transposition` from the :term:`algebra of relations` to the :term:`algebra of clans`, applied to ``clan``, or `Undef()` if ``clan`` is not a :term:`clan`. """ if _checked: if not is_member(clan): return _undef.make_or_raise_undef() else: assert is_member(clan) result = _extension.unary_extend(clan, _functools.partial( _relations.transpose, _checked=False), _checked=False) if not result.is_empty: result.cache_clan(_mo.CacheStatus.IS) result.cache_absolute(clan.cached_absolute) result.cache_functional(clan.cached_right_functional) result.cache_right_functional(clan.cached_functional) result.cache_reflexive(clan.cached_reflexive) result.cache_symmetric(clan.cached_symmetric) result.cache_transitive(clan.cached_transitive) result.cache_regular(clan.cached_right_regular) result.cache_right_regular(clan.cached_regular) return result
def transpose(rel: 'P(M x M)', _checked=True) -> 'P(M x M)': """Return a relation where all couplets have their left and right components swapped. :return: The :term:`unary extension` of :term:`transposition` from the :term:`algebra of couplets` to the :term:`algebra of relations`, applied to the :term:`relation` ``rel``, or `Undef()` if ``rel`` is not a relation. """ if _checked: if not is_member(rel): return _undef.make_or_raise_undef2(rel) else: assert is_member_or_undef(rel) if rel is _undef.Undef(): return _undef.make_or_raise_undef(2) result = _extension.unary_extend(rel, _functools.partial( _couplets.transpose, _checked=False), _checked=False) if not result.is_empty: result.cache_relation(_mo.CacheStatus.IS) result.cache_absolute(rel.cached_absolute) result.cache_functional(rel.cached_right_functional) result.cache_right_functional(rel.cached_functional) result.cache_reflexive(rel.cached_reflexive) result.cache_symmetric(rel.cached_symmetric) result.cache_transitive(rel.cached_transitive) return result
def transpose(clan: 'PP(M x M)', _checked=True) -> 'PP(M x M)': """Return a clan where all relations have their left and right components swapped. :return: The :term:`unary extension` of :term:`transposition` from the :term:`algebra of relations` to the :term:`algebra of clans`, applied to ``clan``, or `Undef()` if ``clan`` is not a :term:`clan`. """ if _checked: if not is_member(clan): return _undef.make_or_raise_undef2(clan) else: assert is_member_or_undef(clan) if clan is _undef.Undef(): return _undef.make_or_raise_undef(2) result = _extension.unary_extend(clan, _functools.partial( _relations.transpose, _checked=False), _checked=False) if not result.is_empty: result.cache_clan(_mo.CacheStatus.IS) result.cache_absolute(clan.cached_absolute) result.cache_functional(clan.cached_right_functional) result.cache_right_functional(clan.cached_functional) result.cache_reflexive(clan.cached_reflexive) result.cache_symmetric(clan.cached_symmetric) result.cache_transitive(clan.cached_transitive) result.cache_regular(clan.cached_right_regular) result.cache_right_regular(clan.cached_regular) return result
def transpose(rel: 'P(M x M)', _checked=True) -> 'P(M x M)': """Return a relation where the left components and right components of all couplets are swapped. :return: The :term:`unary extension` of :term:`transposition` from the :term:`algebra of couplets` to the :term:`algebra of relations`, applied to the :term:`relation` ``rel``, or `Undef()` if ``rel`` is not a relation. """ if _checked: if not is_member(rel): return _make_or_raise_undef() else: assert is_member(rel) return _extension.unary_extend(rel, partial(_couplets.transpose, _checked=False), _checked=False).cache_is_relation(True)
def defined_at(clan, left, _checked=True): r"""Return the :term:`relation`\s of ``clan`` that are defined for ``left``.""" result = _extension.unary_extend( clan, _functools.partial(_relations.defined_at, left=left, _checked=_checked), _checked=_checked) result.cache_clan(_mo.CacheStatus.IS) if not result.is_empty: if clan.cached_is_functional: result.cache_functional(_mo.CacheStatus.IS) if clan.cached_is_right_functional: result.cache_right_functional(_mo.CacheStatus.IS) if clan.cached_is_regular: result.cache_regular(_mo.CacheStatus.IS) if clan.cached_is_right_regular: result.cache_right_regular(_mo.CacheStatus.IS) return result
def transpose(clan: 'PP(M x M)', _checked=True) -> 'PP(M x M)': """Return the :term:`transposition` of the :term:`clan` ``clan``. :return: The :term:`unary extension` of :term:`transposition` from the :term:`algebra of relations` to the :term:`algebra of clans`, applied to ``clan``, or `Undef()` if ``clan`` is not a :term:`clan`. """ if _checked: if not is_member(clan): return _make_or_raise_undef() else: assert is_member(clan) result = _extension.unary_extend(clan, partial(_relations.transpose, _checked=False), _checked=False).cache_is_clan(True) if not result.is_empty: if clan.cached_is_left_functional or clan.cached_is_not_left_functional: result.cache_is_right_functional(clan.cached_is_left_functional) if clan.cached_is_right_functional or clan.cached_is_not_right_functional: result.cache_is_left_functional(clan.cached_is_right_functional) return result
def defined_at(clan: 'PP(M x M)', left: '( M )', _checked=True): r"""Return the :term:`relation`\s of ``clan`` that are defined for ``left``.""" if not is_member(clan): return _undef.make_or_raise_undef(2) if left is _undef.Undef(): return _undef.make_or_raise_undef(2) result = _extension.unary_extend( clan, _functools.partial(_relations.defined_at, left=left, _checked=_checked), _checked=_checked) if result is _undef.Undef() or not result: return _undef.make_or_raise_undef2(result) result.cache_clan(_mo.CacheStatus.IS) if not result.is_empty: if clan.cached_is_functional: result.cache_functional(_mo.CacheStatus.IS) if clan.cached_is_right_functional: result.cache_right_functional(_mo.CacheStatus.IS) if clan.cached_is_regular: result.cache_regular(_mo.CacheStatus.IS) if clan.cached_is_right_regular: result.cache_right_regular(_mo.CacheStatus.IS) return result
def defined_at(clan: 'PP(M x M)', left: '( M )', _checked=True): r"""Return the :term:`relation`\s of ``clan`` that are defined for ``left``.""" if not is_member(clan): return _undef.make_or_raise_undef(2) if left is _undef.Undef(): return _undef.make_or_raise_undef(2) result = _extension.unary_extend(clan, _functools.partial(_relations.defined_at, left=left, _checked=_checked), _checked=_checked) if result is _undef.Undef() or not result: return _undef.make_or_raise_undef2(result) result.cache_clan(_mo.CacheStatus.IS) if not result.is_empty: if clan.cached_is_functional: result.cache_functional(_mo.CacheStatus.IS) if clan.cached_is_right_functional: result.cache_right_functional(_mo.CacheStatus.IS) if clan.cached_is_regular: result.cache_regular(_mo.CacheStatus.IS) if clan.cached_is_right_regular: result.cache_right_regular(_mo.CacheStatus.IS) return result
def test_unary_extend_errors(self): self.assertRaises(AttributeError, lambda: extension.unary_extend(1, sets.big_union))
def test_unary_extend(self): """Verify that unary extend uses the input set and operation to invoke the equivalent operation in next higher power set.""" self.assertEqual(Set(Set(Couplet(1, 1))), extension.unary_extend(Set(*Set(1)), relations.diag))
# the example below, the elements of set_s are numbers, and the elements of powerset_s are sets of # numbers. set_s = Set(1, 2, 3) powerset_s = sets.power_set(set_s) print("S := ", set_s) print("P(S) = ", powerset_s) # Consider that if C is the set of all Couplets, then the set of all relations R can be defined as # P(C), that is, every relation is a subset of the set of all Couplets. It turns out that we can # exploit this relationship by "extending" operations on Couplets up to relations to make them # useful there. To extend a unary operation such as couplets.transpose, we apply it to every # Couplet in a relation, which results in another relation. import algebraixlib.extension as extension first_relation = Set(Couplet('a', 1), Couplet('b', 2), Couplet('c', 3)) transposed_relation = extension.unary_extend(first_relation, couplets.transpose) print("transposed_relation:", transposed_relation) # Similarly, a binary operation like couplets.composition can be extended by applying to every # element of the cross product of two relations. Notice that couplets.composition is a partial # binary operation (given two legitimate Couplets, it may be undefined). When couplets.compose(a, # b) is not defined, it simply isn't included in the membership of the resulting relation. By # extending, we have turned composition into a full binary operation in the power set algebra. second_relation = Set(Couplet('one', 'a'), Couplet('won', 'a'), Couplet('four', 'd')) composed_relation = extension.binary_extend(first_relation, second_relation, couplets.compose) empty_relation = extension.binary_extend( second_relation, first_relation, couplets.compose) # empty relation; still not commutative print("composed_relation:", composed_relation)
def defined_at(clan, left): """Return the portion of clan where relations in clan are defined for left""" clan = _extension.unary_extend(clan, partial( _relations.defined_at, left=left)).cache_is_clan(True) return clan
def test_unary_extend_errors(self): self.assertIs(extension.unary_extend(1, sets.big_union), Undef())
# the example below, the elements of set_s are numbers, and the elements of powerset_s are sets of # numbers. set_s = Set(1, 2, 3) powerset_s = sets.power_set(set_s) print("S := ", set_s) print("P(S) = ", powerset_s) # Consider that if C is the set of all Couplets, then the set of all relations R can be defined as # P(C), that is, every relation is a subset of the set of all Couplets. It turns out that we can # exploit this relationship by "extending" operations on Couplets up to relations to make them useful # there. To extend a unary operation such as couplets.transpose, we apply it to every Couplet in a # relation, which results in another relation. import algebraixlib.extension as extension first_relation = Set(Couplet('a', 1), Couplet('b', 2), Couplet('c', 3)) transposed_relation = extension.unary_extend(first_relation, couplets.transpose) print("transposed_relation:", transposed_relation) # Similarly, a binary operation like couplets.composition can be extended by applying to every element # of the cross product of two relations. Notice that couplets.composition is a partial binary # operation (given two legitimate Couplets, it may be undefined). When couplets.compose(a, b) is # not defined, it simply isn't included in the membership of the resulting relation. By extending, # we have turned composition into a full binary operation in the power set algebra. second_relation = Set(Couplet('one', 'a'), Couplet('won', 'a'), Couplet('four', 'd')) composed_relation = extension.binary_extend(first_relation, second_relation, couplets.compose) empty_relation = extension.binary_extend(second_relation, first_relation, couplets.compose) # empty relation; still not commutative print("composed_relation:", composed_relation) print("empty_relation:", empty_relation) # These extended operations are defined as functions in the relations module.