Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn with substitution of derived classes using equality #24255

Open
rwst opened this issue Nov 21, 2017 · 14 comments
Open

Warn with substitution of derived classes using equality #24255

rwst opened this issue Nov 21, 2017 · 14 comments

Comments

@rwst
Copy link

rwst commented Nov 21, 2017

There is a long-standing problem with substitution in that some substitutions do not work when given as equality but do work when given as dictionary.

sage: (x*pi).subs(x*pi==e)
x*pi
sage: (x*pi).subs({x*pi:e})
e

sage: s = x.series(x,2); s
1*x + Order(x^2)
sage: (x*pi).subs(x*pi==s)
pi*x

It looks like that in some cases the conversion to dict switches lhs and rhs of the equation and this is because of such behaviour:

sage: x*pi==e
e == pi*x
sage: x == s
1*x + Order(x^2) == x

Component: symbolics

Issue created by migration from https://trac.sagemath.org/ticket/24255

@rwst rwst added this to the sage-8.2 milestone Nov 21, 2017
@rwst

This comment has been minimized.

@rwst

This comment has been minimized.

@rwst rwst changed the title Fix substitution with pattern given as equation Fix constants coercion into SR Nov 21, 2017
@rwst

This comment has been minimized.

@rwst rwst changed the title Fix constants coercion into SR Fix constant e coercion into SR Nov 22, 2017
@rwst

This comment has been minimized.

@rwst rwst changed the title Fix constant e coercion into SR Fix Expression subclasses coercion into SR Nov 22, 2017
@rwst

This comment has been minimized.

@rwst

This comment has been minimized.

@rwst
Copy link
Author

rwst commented Nov 23, 2017

comment:7
class A(SageObject):
    def __init__(self):
        from sage.symbolic.ring import SR
        self._parent = SR
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "A"

class B(A):
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "B"

sage: from sage.symbolic.tests import A,B
sage: A() == B()
(B, A)
True

versus

class A():
    def __init__(self):
        from sage.symbolic.ring import SR
        self._parent = SR
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "A"

class B(A):
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "B"

sage: from sage.symbolic.tests import A,B
sage: A() == B()
(A, B)
True

The first has A inherit from SageObject the second not.

@rwst
Copy link
Author

rwst commented Nov 23, 2017

comment:8

Since we cannot use the @richcmp decorator on a cdef class we cannot work around it but must investigate the reason for the argument switching, which is possibly in Cython.

@rwst
Copy link
Author

rwst commented Nov 23, 2017

comment:9

Adding __eq__ does not work I get a Cython compile error reported at cython/cython#2019

@rwst

This comment has been minimized.

@jdemeyer
Copy link

comment:11

Replying to @rwst:

class A(SageObject):
    def __init__(self):
        from sage.symbolic.ring import SR
        self._parent = SR
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "A"

class B(A):
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "B"

sage: from sage.symbolic.tests import A,B
sage: A() == B()
(B, A)
True

versus

class A():
    def __init__(self):
        from sage.symbolic.ring import SR
        self._parent = SR
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "A"

class B(A):
    def __eq__(a, b):
        print(a, b)
        return True
    def __repr__(self):
        return "B"

sage: from sage.symbolic.tests import A,B
sage: A() == B()
(A, B)
True

I think this is just a difference between new-style and old-style classes. This has nothing to do with Cython.

@jdemeyer
Copy link

comment:12

Without any Cython classes involved:

sage: class A(object):
....:     def __eq__(a, b):
....:         print(a, b)
....:         return True
....:     def __repr__(self):
....:         return "A"
....: 
....: class B(A):
....:     def __eq__(a, b):
....:         print(a, b)
....:         return True
....:     def __repr__(self):
....:         return "B"
sage: A() == B()
(B, A)
True

@rwst
Copy link
Author

rwst commented Nov 25, 2017

comment:13

Why then would class A(): not switch arguments? Anyway, this ticket either should warn if subclasses are encountered or at least add explanations to the documentation.

@rwst
Copy link
Author

rwst commented Nov 25, 2017

comment:14

Replying to @rwst:

Why then would class A(): not switch arguments? Anyway, this ticket either should warn if subclasses are encountered or at least add explanations to the documentation.

Okay the answer is https://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python and Python is a PITA.

@rwst rwst changed the title Fix Expression subclasses coercion into SR Warn with substitution of derived classes using equality Nov 25, 2017
@mkoeppe mkoeppe removed this from the sage-8.2 milestone Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants