Source code for algebraixlib.mathobjects.atom

"""An atomic math object that represents a value."""

# $Id: atom.py 22614 2015-07-15 18:14:53Z gfiedler $
# Copyright Algebraix Data Corporation 2015 - $Date: 2015-07-15 13:14:53 -0500 (Wed, 15 Jul 2015) $
#
# This file is part of algebraixlib <http://github.com/AlgebraixData/algebraixlib>.
#
# algebraixlib is free software: you can redistribute it and/or modify it under the terms of version
# 3 of the GNU Lesser General Public License as published by the Free Software Foundation.
#
# algebraixlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with algebraixlib.
# If not, see <http://www.gnu.org/licenses/>.
# --------------------------------------------------------------------------------------------------
import algebraixlib.structure as _structure
from algebraixlib.util.miscellaneous import get_hash as _get_hash

from algebraixlib.mathobjects.mathobject import MathObject


[docs]def auto_convert(arg): """Return always a `MathObject`. If ``arg`` is not a `MathObject`, make it an :class:`Atom`. This function is used in several constructors as convenience wrapper to allow the creation of `MathObject` instances from non-`MathObject` values. """ return arg if isinstance(arg, MathObject) else Atom(arg)
[docs]class Atom(MathObject): """An atomic math object. It represents a value (of a non-`MathObject`, hashable type). .. note:: Instances of :class:`Atom` are considered immutable. Therefore they only accept immutable values. Since an :class:`Atom` also needs to be hashable, the value itself also needs to be hashable. """
[docs] def __new__(cls, value, direct_load=False): """If ``value`` is an :class:`Atom`, return that :class:`Atom`, else return a new :class:`Atom` initialized with ``value``. .. note:: This is used to reduce the number of created :class:`Atom` instances, but doesn't make the check in ``__init__`` unnecessary. ``__init__`` is always called after `__new__`. """ if not direct_load and isinstance(value, Atom): return value return super().__new__(cls)
def __init__(self, value, direct_load=False): """Construct an instance with the given ``value``. :param value: The value of the :class:`Atom`. May not be an instance of `MathObject` other than :class:`Atom`. (If it is of type :class:`Atom`, this :class:`Atom` is used.) The ``value`` must be immutable and hashable. """ if hasattr(self, '_value'): return # Already initialized super().__init__() if direct_load: assert not isinstance(value, MathObject) else: if isinstance(value, MathObject): raise TypeError("'value' must not be a MathObject") self._value = value # NOTE: Non-hashable values will generate TypeError..including Undef() self._hash = _get_hash('algebraixlib.mathobjects.atom.Atom', self._value) @property def value(self): """Read-only; return the value of this instance.""" return self._value
[docs] def get_ground_set(self): """Return the ground set of the lowest-level algebra of this `MathObject`. Is always :math:`A`. """ return _structure.GenesisSetA()
[docs] def get_repr(self): """Return the instance's code representation.""" return 'Atom({value})'.format(value=repr(self._value))
[docs] def get_str(self): """Return the instance's string representation (the string representation of the value).""" return repr(self._value) # ----------------------------------------------------------------------------------------------
[docs] def __eq__(self, other): """A value-based comparison for equality. Return ``True`` if types and values match. NOTE: Atom(1) != Atom(1.0) """ return (isinstance(other, Atom) and isinstance(other.value, type(self.value)) and other.value == self.value)
[docs] def __ne__(self, other): """A value-based comparison for inequality. Return ``True`` if types or values don't match. NOTE: Atom(1) != Atom(1.0) """ return (not isinstance(other, Atom) or not isinstance(other.value, type(self.value)) or other.value != self.value)
def __lt__(self, other): """A value-based comparison for less than. Return ``True`` if ``self < other``.""" return not isinstance(other, Atom) or (repr(self.value) < repr(other.value))
[docs] def __hash__(self): """Return a hash based on the value calculated during construction.""" return self._hash
[docs] def __repr__(self): """Return the instance's code representation.""" return self.get_repr()
[docs] def __str__(self): """Return the instance's string representation.""" return self.get_str()