示例#1
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')
示例#2
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.
示例#3
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_),
    ])
示例#4
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
示例#5
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
示例#6
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
示例#7
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.
示例#8
0
    def transpose(couplet: '(M x M)', _checked=True) -> '(M x M)':
        """Return the transposition of ``couplet`` (right and left components swapped).

        :return: The :term:`transposition` of ``couplet`` or `Undef()` if ``couplet`` is not an
            instance of :class:`~.Couplet`.
        """
        if _checked:
            if not is_member(couplet):
                return _undef.make_or_raise_undef2(couplet)
        else:
            assert is_member_or_undef(couplet)
            if couplet is _undef.Undef():
                return _undef.make_or_raise_undef(2)
        result = _mo.Couplet(left=couplet.right, right=couplet.left, direct_load=True)
        result.cache_absolute(couplet.cached_absolute).cache_reflexive(couplet.cached_reflexive)
        return result
示例#9
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)
示例#10
0
    def compose(couplet1: '(M x M)', couplet2: '(M x M)', _checked=True) -> '(M x M)':
        """Return the composition of ``couplet1`` with ``couplet2``.

        :return: The :term:`composition` of ``couplet1`` with ``couplet2`` (which may be undefined,
            in which case the result is `Undef()`) or `Undef()` if ``couplet1`` or ``couplet2`` are
            not instances of :class:`~.Couplet`.
        """
        if _checked:
            if not is_member(couplet1):
                return _undef.make_or_raise_undef2(couplet1)
            if not is_member(couplet2):
                return _undef.make_or_raise_undef2(couplet2)
        else:
            assert is_member_or_undef(couplet1)
            assert is_member_or_undef(couplet2)
            if couplet1 is _undef.Undef() or couplet2 is _undef.Undef():
                return _undef.make_or_raise_undef(2)
        if couplet1.left != couplet2.right:
            return _undef.make_or_raise_undef(2)
        return _mo.Couplet(left=couplet2.left, right=couplet1.right, direct_load=True)
示例#11
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
示例#12
0
def is_transitive(rel, _checked=True) -> bool:
    """Return whether ``rel`` is transitive.

    :return: ``True`` if ``rel`` is :term:`transitive`, ``False`` if it is not, or `Undef()` if
        ``rel`` is not a :term:`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)
    if rel.cached_transitive == _mo.CacheStatus.UNKNOWN:
        transitive = True
        for couplet1 in rel:
            for couplet2 in rel:
                if couplet1.left == couplet2.right:
                    if not rel.has_element(
                            _mo.Couplet(couplet2.left, couplet1.right)):
                        transitive = False
                        break
        rel.cache_transitive(_mo.CacheStatus.from_bool(transitive))
    return rel.cached_transitive == _mo.CacheStatus.IS
示例#13
0
 def _process_attributes(node):
     for (name, value) in node.attributes.items():
         yield _mo.Couplet(left=_util.get_left_cached(name),
                           right=_mo.Atom(_get_atom_value(value), True),
                           direct_load=True)
示例#14
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)
示例#15
0
def from_dict(dict1: dict) -> 'P(M x M)':
    r"""Return a :term:`relation` where the :term:`couplet`\s are the elements of ``dict1``."""
    return _mo.Set((_mo.Couplet(left, right) for left, right in dict1.items()), direct_load=True)\
        .cache_relation(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)