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

Symbolic functions break the __hash__ contract #14608

Open
vbraun opened this issue May 18, 2013 · 7 comments
Open

Symbolic functions break the __hash__ contract #14608

vbraun opened this issue May 18, 2013 · 7 comments

Comments

@vbraun
Copy link
Member

vbraun commented May 18, 2013

Equal objects must have the same hash if they are hashable (http://docs.python.org/2/reference/datamodel.html#object.__hash__):

sage: my_func = function('func',nargs=1)
sage: f = my_func(0)
sage: bool(f == f.simplify())
True
sage: hash(f) == hash(f.simplify())
False

As reported on http://ask.sagemath.org/question/2587/simplify-shenanigans, hash lookup errors then leads to undesirable behavior:

sage: ex = my_func(0) + my_func(1)
sage: ex.subs(my_func(0)==1)
func(1) + 1
sage: ex.simplify().subs(my_func(0)==1)
func(0) + func(1)

Component: symbolics

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

@vbraun vbraun added this to the sage-5.11 milestone May 18, 2013
@videlec
Copy link
Contributor

videlec commented May 18, 2013

comment:1

Within Sage it is impossible to satisfy "equal objects must have the same hash if they are hashable" because equality is too laxist.

sage: RIF(2) == 2
True
sage: hash(RIF(2))
6400019251
sage: hash(2)
2

Or

sage: bool(pi == RR(pi))
True
sage: hash(pi)
2650685528
sage: hash(RR(pi))
1826823505

You can not hope to solve this problem with one ticket (because the Symbolic ring contains all Sage objects) !

@videlec
Copy link
Contributor

videlec commented May 18, 2013

comment:2

see also http://wiki.sagemath.org/EqualityCoercion.

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented May 18, 2013

comment:3

(cc me)

@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@rwst
Copy link

rwst commented Oct 15, 2015

comment:8

See also #18092.

The problem with simplify+substitute is probably another symptom of NewSymbolicFunctions not being preserved when going through Maxima and, if so, is restricted to user-defined functions. See e.g.

sage: ex = sin(x)+exp(pi)
sage: ex.subs(sin(x)==1)
e^pi + 1
sage: ex.simplify().subs(sin(x)==1)
e^pi + 1

@nbruin
Copy link
Contributor

nbruin commented Nov 9, 2015

comment:9

Now that we've decided to sacrifice readability for reducing the chance of name collisions with variables in conversion from SR to maxima:

sage: x._maxima_()
_SAGE_VAR_x

we could ensure that name translation for functions from SR to maxima is injective as well. Theoretically, we could have

sage: function('f')._maxima_()
_SAGE_FUNC_NAME_f
sage: function('f',nargs=1)._maxima_()
_SAGE_FUNC_NARGS_1_NAME_f

or something similar. Since LISP uses interned strings for symbols, it wouldn't even be inefficient in the "enhanced" interface to maxima_lib: once the dictionaries are seeded, the strings wouldn't be parsed. The strings-based interface would of course have a bit of a penalty, because it does all kind of regex stuff, so string length actually affects performance (but you'd probably have to work very hard to notice it)

Note that this issue came up again on ask sagemath.

@egourgoulhon
Copy link
Member

comment:10

Replying to @nbruin:

Note that this issue came up again on ask sagemath.

There is a recent discussion of this issue on sage-devel.

@egourgoulhon
Copy link
Member

comment:11

It seems to me that the hash issue mentioned in the ticket description has been fixed since at least Sage 9.1. In particular, in Sage 9.1 and Sage 9.3.beta8, we have

sage: my_func = function('func',nargs=1)                                                            
sage: f = my_func(0)                                                                                
sage: bool(f == f.simplify())                                                                       
True
sage: hash(f) == hash(f.simplify())                                                                 
True
sage: ex = my_func(0) + my_func(1)                                                                  
sage: ex.simplify().subs(my_func(0)==1)                                                             
func(1) + 1

Shall we close this ticket?

@mkoeppe mkoeppe removed this from the sage-6.4 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

8 participants