예제 #1
0
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
예제 #2
0
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
예제 #3
0
def partition(set_or_mset, class_invariant_func):
    r"""Return ``set_or_mset`` partitioned according to ``class_invariant_func``.

    :param set_or_mset: The :term:`set` or :term:`multiset` that is to be partitioned.
    :param class_invariant_func: A function from elements of ``set_or_mset`` to
        `MathObject`\s. It defines an :term:`equivalence relation` on ``set_or_mset`` such that

        .. math:: x, y \in set\_or\_mset :
            x \equiv y \iff class\_invariant\_func(x) = class\_invariant\_func(y)

    :return: A set with structure :math:`P(set\_or\_mset.ground\_set)` that defines a partition on
        ``set_or_mset``, imposed by the equivalence relation defined by the function
        ``class_invariant_func``.
    """
    if set_or_mset.is_set:
        partition_dict = _create_partition_dict_from_set(set_or_mset, class_invariant_func)
        # Create the resulting Set of Sets from the partition components.
        return _mo.Set((_mo.Set(components, direct_load=True)
            .cache_clan(set_or_mset.cached_clan)
            for components in partition_dict.values()), direct_load=True)
    elif set_or_mset.is_multiset:
        partition_dict = _create_partition_dict_from_multiset(set_or_mset, class_invariant_func)
        # Create the resulting Set of Multisets from the partition components.
        return _mo.Set((_mo.Multiset(counter, direct_load=True)
            .cache_multiclan(set_or_mset.cached_multiclan)
            for counter in partition_dict.values()), direct_load=True)
    else:
        raise AssertionError('First argument must be Set or Multiset')
예제 #4
0
def make_labeled_partition(set_or_mset, class_invariant_func):
    r"""Return a 'labeled' partition of ``set_or_mset``, partitioned according to
    ``class_invariant_func``.

    :param set_or_mset: The :term:`set` or :term:`multiset` that is to be partitioned.
    :param class_invariant_func: A function from elements of ``set_or_mset`` to `MathObject`\s. It
        defines an :term:`equivalence relation` on ``set_or_mset`` such that

        .. math:: x, y \in set\_or\_mset :
            x \equiv y \iff class\_invariant\_func(x) = class\_invariant\_func(y)

    :return: A :term:`function` with structure :math:`P(range(class\_invariant\_func) \times
        P(set\_or\_mset.ground\_set))` that maps the range of ``class_invariant_func`` when
        applied to ``set_or_mset`` to sets of elements of ``set_or_mset`` that belong to the
        given equivalence class.
    """
    if set_or_mset.is_set:
        partition_dict = _create_partition_dict_from_set(set_or_mset, class_invariant_func)
        return _mo.Set((_mo.Couplet(label, _mo.Set(components, direct_load=True)
                .cache_clan(set_or_mset.cached_clan), direct_load=True)
            for label, components in partition_dict.items()), direct_load=True)
    elif set_or_mset.is_multiset:
        partition_dict = _create_partition_dict_from_multiset(set_or_mset, class_invariant_func)
        return _mo.Set((_mo.Couplet(label, _mo.Multiset(counter, direct_load=True)
                .cache_multiclan(set_or_mset.cached_multiclan), direct_load=True)
            for label, counter in partition_dict.items()), direct_load=True)
    else:
        raise AssertionError('First argument must be Set or Multiset')
예제 #5
0
def from_dict(dict1: dict) -> 'PP(M x M)':
    r"""Return a :term:`clan` with a single :term:`relation` where the :term:`couplet`\s are the
    elements of ``dict1``."""
    rel = _mo.Set((_mo.Couplet(left, right) for left, right in dict1.items()),
                  direct_load=True)
    rel.cache_relation(_mo.CacheStatus.IS)
    rel.cache_functional(_mo.CacheStatus.IS)
    clan = _mo.Set(rel, direct_load=True)
    clan.cache_clan(_mo.CacheStatus.IS)
    clan.cache_functional(_mo.CacheStatus.IS)
    clan.cache_regular(_mo.CacheStatus.IS)
    return clan
예제 #6
0
def power_up(set_: _mo.Set):
    """'Add a set of braces' around the elements of ``set_``.

    :return: A :class:`~.Set` where every element is a ``Set`` that contains exactly one element
        of ``set_`` and where there is exactly one element-``Set`` for every element of ``set_``.
    """
    if not is_member(set_):
        return _undef.make_or_raise_undef2(set_)
    result = _mo.Set((_mo.Set(element) for element in set_), direct_load=True)
    if not result.is_empty:
        if set_.cached_is_relation:
            result.cache_clan(_mo.CacheStatus.IS)
            result.cache_absolute(set_.cached_absolute)
            result.cache_functional(_mo.CacheStatus.IS)
            result.cache_right_functional(_mo.CacheStatus.IS)
    return result
예제 #7
0
 def _process_nodes(nodes):
     for node in nodes:
         if node.nodeType == node.ELEMENT_NODE:
             # attributes and children are sets of Couplets.
             attributes = set(_process_attributes(node))
             children = set(_process_nodes(
                 node.childNodes))  # May include text (text_left).
             children = children.union(attributes)
             if len(children) == 1 and _contains_text_node(children):
                 # We have a single child that is a text node. Remove one layer of couplets.
                 yield _mo.Couplet(
                     left=_util.get_left_cached(node.tagName),
                     right=_misc.get_single_iter_elem(children).right,
                     direct_load=True)
             else:
                 yield _mo.Couplet(left=_util.get_left_cached(node.tagName),
                                   right=_mo.Set(children,
                                                 direct_load=True),
                                   direct_load=True)
         elif node.nodeType == node.TEXT_NODE:
             text_node_text = node.data.strip()
             if len(text_node_text) > 0:
                 yield _mo.Couplet(left=text_left,
                                   right=_mo.Atom(
                                       _get_atom_value(text_node_text),
                                       direct_load=True),
                                   direct_load=True)
         else:
             assert False  # Node type not supported.
예제 #8
0
def _check_graph(obj: _mo.MathObject) -> bool:
    """Return ``True`` if ``obj`` is a :term:`graph`, ``False`` if not.

    ``obj`` is expected to be a :term:`clan`.
    """
    return obj.is_set and obj.get_left_set() == _mo.Set('s', 'p', 'o') \
        and _properties.is_regular(obj)
예제 #9
0
def binary_extend(set1: 'P( M )',
                  set2: 'P( M )',
                  op,
                  _checked=True) -> 'P( M )':
    r"""Return the :term:`binary extension` of ``op`` from one :term:`algebra` to another algebra.

    For this extension, the elements of the extended algebra must be :term:`set`\s of the
    elements of the original algebra.

    :param set1: A :term:`set` with elements on which ``op`` operates.
    :param set2: A set with elements on which ``op`` operates.
    :param op: A :term:`binary operation` that operates on the elements of ``set1`` and ``set2``.
    :return: A set that consists of the defined results of ``op`` when executed on all combinations
        of the elements of ``set1`` and ``set2``, or `Undef()` if either set is not a
        :class:`~.Set`.
    """
    if _checked:
        if not _sets.is_member(set1):
            return _undef.make_or_raise_undef2(set1)
        if not _sets.is_member(set2):
            return _undef.make_or_raise_undef2(set2)
    else:
        assert _sets.is_member_or_undef(set1)
        assert _sets.is_member_or_undef(set2)
        if set1 is _undef.Undef() or set2 is _undef.Undef():
            return _undef.make_or_raise_undef(2)

    def _get_values(_set1, _set2):
        for e1 in _set1:
            for e2 in _set2:
                result = op(e1, e2)
                if result is not _undef.Undef():
                    yield result

    return _mo.Set(_get_values(set1, set2), direct_load=True)
예제 #10
0
def object_hook_f(obj):
    """``obj`` is a representation of a straightforward translation of JSON into Python. For a known
    special construct (must be a ``dict``), convert it into its correct object representation and
    return it. Otherwise return ``obj`` as-is. (May be used as ``object_hook`` function for the
    various JSON decoder APIs.)
    """
    if len(obj) == 2 and '__cls__' in obj and '__val__' in obj:
        if obj['__cls__'] == 'builtin.bytes':
            return bytes(elem for elem in obj['__val__'])
        if obj['__cls__'] == 'builtin.complex':
            return complex(obj['__val__'])
        if obj['__cls__'] == 'builtin.frozenset':
            return frozenset(decode(elem) for elem in obj['__val__'])
        if obj['__cls__'] == 'builtin.list':
            return list(decode(elem) for elem in obj['__val__'])
        if obj['__cls__'] == 'builtin.range':
            return range(decode(obj['__val__'][0]), decode(obj['__val__'][1]),
                         decode(obj['__val__'][2]))
        if obj['__cls__'] == 'builtin.tuple':
            return tuple(decode(elem) for elem in obj['__val__'])
        if obj['__cls__'] == 'Atom':
            return _mo.Atom(decode(obj['__val__']), direct_load=True)
        if obj['__cls__'] == 'Couplet':
            return _mo.Couplet(left=decode(obj['__val__'][0]),
                               right=decode(obj['__val__'][1]),
                               direct_load=True)
        if obj['__cls__'] == 'Set':
            return _mo.Set((decode(elem) for elem in obj['__val__']),
                           direct_load=True)
        if obj['__cls__'] == 'Multiset':
            return _mo.Multiset(
                {decode(val): mult
                 for val, mult in obj['__val__']},
                direct_load=True)
    return obj
예제 #11
0
def demultify(multiset: 'P( M x N )', _checked=True) -> 'P( M )':
    """Return a :term:`set` based on ``multiset`` that contains all elements without multiples."""
    if _checked:
        if not is_member(multiset):
            return _undef.make_or_raise_undef2(multiset)
    else:
        assert is_member_or_undef(multiset)
        if multiset is _undef.Undef():
            return _undef.make_or_raise_undef(2)
    result = _mo.Set(multiset.data.keys(), direct_load=True)
    if not result.is_empty:
        result.cache_clan(multiset.cached_multiclan)
        if multiset.cached_is_multiclan:
            result.cache_absolute(multiset.cached_absolute)
            result.cache_functional(multiset.cached_functional)
            result.cache_right_functional(multiset.cached_right_functional)
            result.cache_reflexive(multiset.cached_reflexive)
            result.cache_symmetric(multiset.cached_symmetric)
            result.cache_transitive(multiset.cached_transitive)
            result.cache_regular(multiset.cached_regular)
            result.cache_right_regular(multiset.cached_right_regular)
        # We don't yet have a concept of multirelations (multisets of couplets). Because of this,
        # a multiset that is converted into a set may be a relation without us being able to know
        # this here. Because of this, the only flags we can propagate are multiclan flags.
    return result
예제 #12
0
def _check_triple(obj: 'P(A x M)') -> bool:
    """Return ``True`` if ``obj`` is a :term:`triple`, ``False`` if not.

    ``obj`` is expected to be a :term:`relation`.
    """
    # noinspection PyUnresolvedReferences
    return obj.is_set and obj.cardinality == 3 and obj.get_left_set(
    ) == _mo.Set('s', 'p', 'o')
예제 #13
0
def power_set(set_: _mo.Set):
    """Return the :term:`power set` of ``set_``."""
    if not is_member(set_):
        return _undef.make_or_raise_undef2(set_)
    from itertools import combinations
    result = []
    for subset_size in range(set_.cardinality + 1):
        subset_combinations = combinations(set_, subset_size)
        result.extend(_mo.Set(comb) for comb in subset_combinations)
    result = _mo.Set(result)
    if not result.is_empty:
        if set_.cached_is_relation:
            result.cache_clan(_mo.CacheStatus.IS)
            result.cache_absolute(set_.cached_absolute)
            result.cache_functional(set_.cached_functional)
            result.cache_right_functional(set_.cached_right_functional)
            result.cache_regular(_mo.CacheStatus.IS_NOT)
            result.cache_right_regular(_mo.CacheStatus.IS_NOT)
    return result
예제 #14
0
def functional_add(func: 'P(M x M)', element: 'M x M') -> 'P(M x M)':
    """Add ``element`` to ``func`` and return the new functional relation.

    :param func: The source data. Must be a :term:`function`. It must not contain a :term:`couplet`
        with the same :term:`left component` as ``element``.
    :param element: The element to be added to ``func``. Must be a :class:`~.Couplet` and its
        :term:`left component` must not be a left component in ``func``.
    :return: The new relation, composed of ``func`` and ``element``.
    """
    if not is_member(func) or not is_functional(func):
        return _undef.make_or_raise_undef2(func)
    if not _couplets.is_member(element):
        return _undef.make_or_raise_undef2(element)
    if _sets.is_subset_of(_mo.Set(element.left), get_lefts(func)):
        return _undef.make_or_raise_undef(2)
    element_func = _mo.Set(element).cache_relation(_mo.CacheStatus.IS)
    result = _sets.union(func, element_func)
    assert result.cached_is_relation and is_functional(result)
    result.cache_functional(_mo.CacheStatus.IS)
    return result
예제 #15
0
def diag(*args, _checked=True) -> 'P(M x M)':
    """Return the :term:`diagonal` of the set comprising the elements in ``*args``."""
    for element in args:
        if element is _undef.Undef():
            return _undef.make_or_raise_undef(2)
    rel = _mo.Set((_mo.Couplet(el, direct_load=not _checked) for el in args),
                  direct_load=True)
    rel.cache_relation(CacheStatus.IS)
    rel.cache_functional(CacheStatus.IS).cache_right_functional(CacheStatus.IS)
    rel.cache_reflexive(CacheStatus.IS).cache_symmetric(CacheStatus.IS)
    return rel
예제 #16
0
def make_triple(subject: '( M )', predicate: '( M )',
                object_: '( M )') -> 'P(A x M)':
    """Return an RDF `triple`, created from ``subject``, ``predicate`` and ``object_``.

    Each of the arguments must be an instance of `MathObject` or a Python type that automatically
    converts to an :class:`~.Atom` in the :class:`~.Couplet` constructor.
    """
    return _mo.Set([
        _mo.Couplet(left='s', right=subject),
        _mo.Couplet(left='p', right=predicate),
        _mo.Couplet(left='o', right=object_),
    ])
예제 #17
0
def from_set(left: '( M )', *values: '( M )') -> 'PP(M x M)':
    r"""Return a clan where all relations contain a single couplet with the same left component.

    :param left: The :term:`left component` of all :term:`couplet`\s in the returned :term:`clan`.
    :param values: The :term:`right component`\s of the couplets in the returned clan. (If you want
        to pass in an iterable, you need to prefix it with an asterisk ``*``.)
    :return: A clan where every :term:`relation` consists of a single couplet with a left component
        of ``left`` and a right component from ``values``.
    """
    left_mo = _mo.auto_convert(left)
    clan = _mo.Set((_mo.Set(
        _mo.Couplet(left_mo, _mo.auto_convert(right), direct_load=True),
        direct_load=True).cache_relation(CacheStatus.IS).cache_functional(
            CacheStatus.IS).cache_right_functional(CacheStatus.IS)
                    for right in values),
                   direct_load=True)
    clan.cache_clan(CacheStatus.IS)
    clan.cache_functional(CacheStatus.IS).cache_right_functional(
        CacheStatus.IS)
    clan.cache_regular(CacheStatus.IS).cache_right_regular(CacheStatus.IS)
    return clan
예제 #18
0
 def _process_nodes(nodes):
     if isinstance(nodes, list):
         for list_data in nodes:
             yield _mo.Set(*list(_process_nodes(list_data)))
     else:
         for key, value in nodes.items():
             if isinstance(value, list):
                 for list_data in value:
                     child = _process_nodes(list_data)
                     yield _mo.Couplet(_mo.Atom(key),
                                       _mo.Set(child),
                                       direct_load=True)
             elif isinstance(value, dict):
                 children = _process_nodes(value)
                 yield _mo.Couplet(_mo.Atom(key),
                                   _mo.Set(children),
                                   direct_load=True)
             elif isinstance(value, (str, int)):
                 yield _mo.Couplet(_mo.Atom(key),
                                   _mo.Atom(value),
                                   direct_load=True)
             else:
                 assert False  # Node type not supported.
예제 #19
0
    def lhs_cross_functional_union(lhs: 'PP( MxM )',
                                   rhs: 'PP( MxM )',
                                   _checked=True) -> 'PP(M x M)':
        """Return the :term:`lhs-cross-functional union` ('left join') of ``lhs`` and ``rhs``.

        This operation results in a :term:`clan` that contains every :term:`relation` of a
        :term:`cross-functional union`, but also contains all relations in ``lhs`` that
        are not already part of one of the resulting relations.

        :param lhs: All relations in this clan are guaranteed to be represented in the result.
        :return: The resulting clan or `Undef()` if ``lhs`` or ``rhs`` are not clans.
        """
        if _checked:
            if not is_member(lhs):
                return _undef.make_or_raise_undef2(lhs)
            if not is_member(rhs):
                return _undef.make_or_raise_undef2(rhs)
        else:
            assert is_member_or_undef(lhs)
            assert is_member_or_undef(rhs)
            if lhs is _undef.Undef() or rhs is _undef.Undef():
                return _undef.make_or_raise_undef(2)
        cfu = cross_functional_union(lhs, rhs, _checked=False)
        lhs_rest = _mo.Set(
            lhs_elem for lhs_elem in lhs if cross_functional_union(
                _mo.Set(lhs_elem, direct_load=True), rhs).is_empty)
        result = _sets.union(cfu, lhs_rest, _checked=False)
        if not result.is_empty:
            result.cache_clan(_mo.CacheStatus.IS)
            if lhs.cached_is_functional:
                result.cache_functional(_mo.CacheStatus.IS)
            if lhs.cached_is_not_right_functional or rhs.cached_is_not_right_functional:
                result.cache_right_functional(_mo.CacheStatus.IS_NOT)
            if not rhs.is_empty and not lhs_rest.is_empty:
                result.cache_regular(_mo.CacheStatus.IS_NOT)
        return result
예제 #20
0
    def minus(set1: 'P( M )', set2: 'P( M )', _checked=True) -> 'P( M )':
        r"""Return the set difference of ``set1`` and ``set2``.

        :return: The :term:`difference` of ``set1`` and ``set2`` or `Undef()` if ``set1`` or
            ``set2`` are not :term:`set`\s (that is, instances of :class:`~.Set`).
        """
        # pylint: disable=too-many-branches
        if _checked:
            if not is_member(set1):
                return _undef.make_or_raise_undef2(set1)
            if not is_member(set2):
                return _undef.make_or_raise_undef2(set2)
        else:
            assert is_member_or_undef(set1)
            assert is_member_or_undef(set2)
            if set1 is _undef.Undef() or set2 is _undef.Undef():
                return _undef.make_or_raise_undef(2)
        result = _mo.Set(set1.data.difference(set2.data), direct_load=True)
        if not result.is_empty:
            # Relation flags:
            if set1.cached_is_relation:
                result.cache_relation(_mo.CacheStatus.IS)
                if set1.cached_is_absolute:
                    result.cache_absolute(_mo.CacheStatus.IS)
                if set1.cached_is_functional:
                    result.cache_functional(_mo.CacheStatus.IS)
                if set1.cached_is_right_functional:
                    result.cache_right_functional(_mo.CacheStatus.IS)
            # Clan flags:
            if set1.cached_is_clan:
                result.cache_clan(_mo.CacheStatus.IS)
                if set1.cached_is_absolute:
                    result.cache_absolute(_mo.CacheStatus.IS)
                if set1.cached_is_functional:
                    result.cache_functional(_mo.CacheStatus.IS)
                if set1.cached_is_right_functional:
                    result.cache_right_functional(_mo.CacheStatus.IS)
                if set1.cached_is_reflexive:
                    result.cache_reflexive(_mo.CacheStatus.IS)
                if set1.cached_is_symmetric:
                    result.cache_symmetric(_mo.CacheStatus.IS)
                if set1.cached_is_transitive:
                    result.cache_transitive(_mo.CacheStatus.IS)
                if set1.cached_is_regular:
                    result.cache_regular(_mo.CacheStatus.IS)
                if set1.cached_is_right_regular:
                    result.cache_right_regular(_mo.CacheStatus.IS)
        return result
예제 #21
0
def diag(*args, _checked=True) -> 'PP(M x M)':
    """Return a clan diagonal of the arguments.

    :param args: Pass in the elements from which the :term:`clan diagonal` is formed. (If you want
        to pass in an iterable, you need to prefix it with an asterisk ``*``.)
    """
    rels = _relations.diag(*args, _checked=_checked)
    if rels is _undef.Undef():
        return _undef.make_or_raise_undef(2)
    clan = _mo.Set(rels, direct_load=True)
    clan.cache_clan(CacheStatus.IS)
    clan.cache_functional(CacheStatus.IS).cache_right_functional(
        CacheStatus.IS)
    clan.cache_reflexive(CacheStatus.IS).cache_symmetric(CacheStatus.IS)
    clan.cache_regular(CacheStatus.IS).cache_right_regular(CacheStatus.IS)
    return clan
예제 #22
0
def get_rights(rel: 'P(M x M)', _checked=True) -> 'P( M )':
    """Return the set of the right components of all couplets in the relation ``rel``.

    :return: The :term:`right set` of 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 = _mo.Set((e.right for e in rel), direct_load=True)
    if not result.is_empty:
        if rel.cached_is_absolute:
            result.cache_absolute(_mo.CacheStatus.IS)
    return result
예제 #23
0
def restrict(set_: 'P( M )', selector: _collections.Callable) -> 'P( M )':
    """Return a set with all the elements from ``set_`` for which the predicate ``selector`` returns
    ``True``.

    :param set_: The source data. Must be a :term:`set`.
    :param selector: A :class:`~collections.abc.Callable` that accepts as single argument a
        :class:`~.MathObject` and returns a `bool` that indicates whether the element is
        in the result set (``True``) or not (``False``).
    """
    # pylint: disable=too-many-branches
    if not is_member(set_):
        return _undef.make_or_raise_undef2(set_)
    result = _mo.Set((element for element in set_ if selector(element)),
                     direct_load=True)
    if not result.is_empty:
        # Relation flags:
        if set_.cached_is_relation:
            result.cache_relation(_mo.CacheStatus.IS)
            if set_.cached_is_absolute:
                result.cache_absolute(_mo.CacheStatus.IS)
            if set_.cached_is_functional:
                result.cache_functional(_mo.CacheStatus.IS)
            if set_.cached_is_right_functional:
                result.cache_right_functional(_mo.CacheStatus.IS)
        # Clan flags:
        if set_.cached_is_clan:
            result.cache_clan(_mo.CacheStatus.IS)
            if set_.cached_is_absolute:
                result.cache_absolute(_mo.CacheStatus.IS)
            if set_.cached_is_functional:
                result.cache_functional(_mo.CacheStatus.IS)
            if set_.cached_is_right_functional:
                result.cache_right_functional(_mo.CacheStatus.IS)
            if set_.cached_is_reflexive:
                result.cache_reflexive(_mo.CacheStatus.IS)
            if set_.cached_is_symmetric:
                result.cache_symmetric(_mo.CacheStatus.IS)
            if set_.cached_is_transitive:
                result.cache_transitive(_mo.CacheStatus.IS)
            if set_.cached_is_regular:
                result.cache_regular(_mo.CacheStatus.IS)
            if set_.cached_is_right_regular:
                result.cache_right_regular(_mo.CacheStatus.IS)
    return result
예제 #24
0
    def intersect(set1: 'P( M )', set2: 'P( M )', _checked=True) -> 'P( M )':
        r"""Return the intersection of ``set1`` with ``set2``.

        :return: The :term:`binary intersection` of ``set1`` and ``set2`` or `Undef()` if ``set1``
            or ``set2`` are not :term:`set`\s (that is, instances of :class:`~.Set`).
        """
        # pylint: disable=too-many-branches
        if _checked:
            if not is_member(set1):
                return _undef.make_or_raise_undef2(set1)
            if not is_member(set2):
                return _undef.make_or_raise_undef2(set2)
        else:
            assert is_member_or_undef(set1)
            assert is_member_or_undef(set2)
            if set1 is _undef.Undef() or set2 is _undef.Undef():
                return _undef.make_or_raise_undef(2)
        values = set1.data.intersection(set2.data)
        result = _mo.Set(values, direct_load=True)
        if not result.is_empty:
            # Relation flags:
            if set1.cached_is_relation or set2.cached_is_relation:
                result.cache_relation(_mo.CacheStatus.IS)
                if set1.cached_is_absolute or set2.cached_is_absolute:
                    result.cache_absolute(_mo.CacheStatus.IS)
                if set1.cached_is_functional or set2.cached_is_functional:
                    result.cache_functional(_mo.CacheStatus.IS)
                if set1.cached_is_right_functional or set2.cached_is_right_functional:
                    result.cache_right_functional(_mo.CacheStatus.IS)
            # Clan flags:
            if set1.cached_is_clan or set2.cached_is_clan:
                result.cache_clan(_mo.CacheStatus.IS)
                if set1.cached_is_absolute or set2.cached_is_absolute:
                    result.cache_absolute(_mo.CacheStatus.IS)
                if set1.cached_is_functional or set2.cached_is_functional:
                    result.cache_functional(_mo.CacheStatus.IS)
                if set1.cached_is_right_functional or set2.cached_is_right_functional:
                    result.cache_right_functional(_mo.CacheStatus.IS)
                if set1.cached_is_regular or set2.cached_is_regular:
                    result.cache_regular(_mo.CacheStatus.IS)
                if set1.cached_is_right_regular or set2.cached_is_right_regular:
                    result.cache_right_regular(_mo.CacheStatus.IS)
        return result
예제 #25
0
    def _import_csv(csv_file):
        for _ in range(0, skip_rows):
            next(csv_file)
        reader = _csv.DictReader(csv_file, fieldnames=columns)

        _index = 0
        for row in reader:
            filtered_row = {key: val for key, val in _filter_row(row)}
            if import_csv.regular and len(row) != len(filtered_row):
                import_csv.regular = False
            for key, val in types.items():
                if key in filtered_row:
                    filtered_row[key] = val(filtered_row[key])
            if index_column is not None:
                filtered_row[index_column] = _index
                _index += 1
            yield _mo.Set(
                (_mo.Couplet(left=_util.get_left_cached(left), right=_mo.Atom(right),
                direct_load=True) for left, right in filtered_row.items()), direct_load=True)\
                .cache_relation(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)
예제 #26
0
def import_csv(csv_file_or_filepath,
               types: {} = None,
               skip_rows: int = 0,
               index_column: str = None,
               has_dup_rows: bool = False,
               columns: [] = None) -> 'PP( A x M )':
    r"""Import the file ``csv_file_or_filepath`` as CSV data and return a clan or multiclan.

    :param csv_file_or_filepath: The file path or file object (for example ``StringIO`` buffer) to
        import.
    :param types: (Optional) A dictionary of type conversions. The keys are the column names; the
        values are functors (or types) that receive the string from the CSV cell and return the
        value to be imported. Example: ``{'foo': int, 'bar': float}``. By default all values are
        interpreted as `string`\s.
    :param skip_rows: (Optional) A number of lines to skip (default 0). Some CSV files have a
        preamble that can be skipped with this option.
    :param index_column: (Optional) A name for an index column. (No index column is created if this
        argument is not specified.) The index starts with 0. (This option is not compatible with the
        ``has_dup_rows`` option.)
    :param has_dup_rows: (Optional) If ``True``, allow duplicate rows and return a multiclan
        instead of a clan. By default, the value is ``False`` and a clan is returned. (This option
        is not compatible with the option ``index_column``.)
    :param columns: (Optional) A list of column names. If present, this list is used as the
        sequence of columns (and all lines in the data are loaded). If missing, the first line of
        the data must be a header that contains the column names (and this header line is not
        loaded as data).
    :return: A :term:`clan` (if ``has_dup_rows is ``False`` or not provided) or a :term:`multiclan`
        (if ``has_dup_rows`` is ``True``).
    """
    if types is None:
        types = {}

    def _filter_row(row):
        """Remove missing and blank elements from the CSV row."""
        for key, val in row.items():
            if val is None or val == '':
                continue
            yield key, val

    _util.get_left_cached.left_cache = {}
    import_csv.regular = True  # Set to false if any row is missing one or more values

    assert ((index_column is not None) &
            (has_dup_rows is False)) or (index_column is None)

    def _import_csv(csv_file):
        for _ in range(0, skip_rows):
            next(csv_file)
        reader = _csv.DictReader(csv_file, fieldnames=columns)

        _index = 0
        for row in reader:
            filtered_row = {key: val for key, val in _filter_row(row)}
            if import_csv.regular and len(row) != len(filtered_row):
                import_csv.regular = False
            for key, val in types.items():
                if key in filtered_row:
                    filtered_row[key] = val(filtered_row[key])
            if index_column is not None:
                filtered_row[index_column] = _index
                _index += 1
            yield _mo.Set(
                (_mo.Couplet(left=_util.get_left_cached(left), right=_mo.Atom(right),
                direct_load=True) for left, right in filtered_row.items()), direct_load=True)\
                .cache_relation(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)

    if hasattr(csv_file_or_filepath, "readlines"):  # Support StringIO.
        if has_dup_rows:
            return _mo.Multiset(_import_csv(csv_file_or_filepath),
                                direct_load=True).cache_multiclan(
                                    _mo.CacheStatus.IS).cache_functional(
                                        _mo.CacheStatus.IS).cache_regular(
                                            _mo.CacheStatus.from_bool(
                                                import_csv.regular))
        else:
            return _mo.Set(_import_csv(csv_file_or_filepath), direct_load=True)\
                .cache_clan(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)\
                .cache_regular(_mo.CacheStatus.from_bool(import_csv.regular))
    else:
        with open(csv_file_or_filepath, encoding='utf-8',
                  errors='ignore') as file:
            if has_dup_rows:
                return _mo.Multiset(
                    _import_csv(file), direct_load=True).cache_multiclan(
                        _mo.CacheStatus.IS).cache_functional(
                            _mo.CacheStatus.IS).cache_regular(
                                _mo.CacheStatus.from_bool(import_csv.regular))
            else:
                return _mo.Set(_import_csv(file), direct_load=True)\
                    .cache_clan(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)\
                    .cache_regular(_mo.CacheStatus.from_bool(import_csv.regular))
예제 #27
0
def _convert_graph_to_mathobjects(rdflib_graph: _rdflib.Graph) -> 'PP(A x A)':
    """Return a `graph` from the data in the `~_rdflib.Graph` `rdflib_graph`."""
    return _mo.Set(
        _make_triple_from_graph(triple_tuple) for triple_tuple in rdflib_graph)
예제 #28
0
        "result multiset.\n")

# Multiset Intersect Operation Example
simple_minus = _multisets.minus(ms_1, ms_2)

print(str(ms_1) + ' MINUS ' + str(ms_2))
print('=> EVALUATES TO ' + str(simple_minus))

ms_6 = _mo.Multiset({'a': 3, 'b': 1})
if ms_6 == simple_minus:
    print("multiset's minus subtracts all the rhs multiples from the lhs.\n")

# Moving on to multiclan examples now

# Setting up multiclan relations
rel_1 = _mo.Set(_mo.Couplet('x', 'y'), _mo.Couplet('w', 'y'))
rel_2 = _mo.Set(_mo.Couplet('a', 'x'), _mo.Couplet('b', 'w'))
rel_3 = _mo.Set(_mo.Couplet('x', 'z'), _mo.Couplet('v', 'y'))
rel_4 = _mo.Set(_mo.Couplet('c', 'z'), _mo.Couplet('a', 'v'))
rel_5 = _mo.Set(_mo.Couplet('b', 'w'), _mo.Couplet('w', 'y'))
rel_6 = _mo.Set(_mo.Couplet('a', 'x'), _mo.Couplet('x', 'y'))

# Creating multiclans (multisets of relations)
mc_1 = _mo.Multiset({rel_1: 2, rel_3: 3})
mc_2 = _mo.Multiset({rel_2: 5, rel_4: 1})
mc_3 = _mo.Multiset({rel_1: 2, rel_6: 7})
mc_4 = _mo.Multiset({rel_2: 5, rel_5: 11})

# Multiset Transpose Operation Example
simple_transpose = _multiclans.transpose(mc_1)
예제 #29
0
 def _import_json(json_file):
     import json
     tree = json.load(json_file)
     return _mo.Set(_process_nodes(tree), direct_load=True)
예제 #30
0
 def _import_xml(xml_file):
     import xml.dom.minidom
     tree = xml.dom.minidom.parse(xml_file)
     return _mo.Set(_process_nodes(tree.childNodes), direct_load=True)