1""" The core's core. """
2
3# used for canonical ordering of symbolic sequences
4# via __cmp__ method:
5# FIXME this is *so* irrelevant and outdated!
6ordering_of_classes = [
7    # singleton numbers
8    'Zero', 'One', 'Half', 'Infinity', 'NaN', 'NegativeOne', 'NegativeInfinity',
9    # numbers
10    'Integer', 'Rational', 'Float',
11    # singleton symbols
12    'Exp1', 'Pi', 'ImaginaryUnit',
13    # symbols
14    'Symbol', 'Wild', 'Temporary',
15    # arithmetic operations
16    'Pow', 'Mul', 'Add',
17    # function values
18    'Derivative', 'Integral',
19    # defined singleton functions
20    'Abs', 'Sign', 'Sqrt',
21    'Floor', 'Ceiling',
22    'Re', 'Im', 'Arg',
23    'Conjugate',
24    'Exp', 'Log',
25    'Sin', 'Cos', 'Tan', 'Cot', 'ASin', 'ACos', 'ATan', 'ACot',
26    'Sinh', 'Cosh', 'Tanh', 'Coth', 'ASinh', 'ACosh', 'ATanh', 'ACoth',
27    'RisingFactorial', 'FallingFactorial',
28    'factorial', 'binomial',
29    'Gamma', 'LowerGamma', 'UpperGamma', 'PolyGamma',
30    'Erf',
31    # special polynomials
32    'Chebyshev', 'Chebyshev2',
33    # undefined functions
34    'Function', 'WildFunction',
35    # anonymous functions
36    'Lambda',
37    # Landau O symbol
38    'Order',
39    # relational operations
40    'Equality', 'Unequality', 'StrictGreaterThan', 'StrictLessThan',
41    'GreaterThan', 'LessThan',
42]
43
44
45class Registry:
46    """
47    Base class for registry objects.
48
49    Registries map a name to an object using attribute notation. Registry
50    classes behave singletonically: all their instances share the same state,
51    which is stored in the class object.
52
53    All subclasses should set `__slots__ = ()`.
54    """
55    __slots__ = ()
56
57    def __setattr__(self, name, obj):
58        setattr(self.__class__, name, obj)
59
60    def __delattr__(self, name):
61        delattr(self.__class__, name)
62
63#A set containing all sympy class objects
64all_classes = set()
65
66
67class BasicMeta(type):
68
69    def __init__(cls, *args, **kws):
70        all_classes.add(cls)
71        cls.__sympy__ = property(lambda self: True)
72
73    def __cmp__(cls, other):
74        # If the other object is not a Basic subclass, then we are not equal to
75        # it.
76        if not isinstance(other, BasicMeta):
77            return -1
78        n1 = cls.__name__
79        n2 = other.__name__
80        if n1 == n2:
81            return 0
82
83        UNKNOWN = len(ordering_of_classes) + 1
84        try:
85            i1 = ordering_of_classes.index(n1)
86        except ValueError:
87            i1 = UNKNOWN
88        try:
89            i2 = ordering_of_classes.index(n2)
90        except ValueError:
91            i2 = UNKNOWN
92        if i1 == UNKNOWN and i2 == UNKNOWN:
93            return (n1 > n2) - (n1 < n2)
94        return (i1 > i2) - (i1 < i2)
95
96    def __lt__(cls, other):
97        if cls.__cmp__(other) == -1:
98            return True
99        return False
100
101    def __gt__(cls, other):
102        if cls.__cmp__(other) == 1:
103            return True
104        return False
105