sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.39k stars 473 forks source link

Hash for fraction field element is too permissive #35238

Open xcaruso opened 1 year ago

xcaruso commented 1 year ago

Is there an existing issue for this?

Did you read the documentation and troubleshoot guide?

Environment

- **OS**: Ubuntu 20.04
- **Sage Version**: 10.0.beta1

Steps To Reproduce

sage: A.<x,y> = QQ[]
sage: K = A.fraction_field()
sage: d = { x/y: 0 }
sage: d[K(2*x, 2*y)]
Traceback (most recent call last):
...
KeyError: 2*x/(2*y)

Expected Behavior

(2*x)/(2*y) is equal to x/y, so d[K(2*x, 2*y)] should return 0.

Actual Behavior

The reason why it fails is that x/y and (2*x)/(2*y) through they are considered as equal by equality test.

Additional Information

No response

tehami02 commented 1 year ago

@xcaruso I have worked on this problem and I think this could probably be the reason - The reason why d[K(2x, 2y)] does not return 0 is because the derivative of K(2x, 2y) with respect to x and y is not zero.

While 2x/(2y) simplifies to x/y, their derivatives with respect to x and y are not the same. Specifically, the derivative of 2x/(2y) with respect to x is 2/(2*y), which simplifies to 1/y. On the other hand, the derivative of x/y with respect to x is 1/y, which is the same.

But when taking the partial derivative of K(2x, 2y) with respect to x, we get 2yexp(2xy), which is not zero. Similarly, when taking the partial derivative of K(2x, 2y) with respect to y, we get 2xexp(2xy), which is also not zero.

In summary, just because two expressions are algebraically equivalent does not mean that their derivatives will be the same.

xcaruso commented 1 year ago

Sorry, I don't understand your answer; how do you get these weird expression 2yexp(2xy) and 2xexp(2xy)?

videlec commented 1 year ago

@xcaruso You did not defined K. I guess you forgot K = A.fraction_field()...

videlec commented 1 year ago

To my mind, the only reasonable default for fraction field element hash is to always return 0. But then, it does not make much sense to use these in a set or as keys of a dict. If you have additional structure on the ring (eg Euclidean domain, PID, grading) then smarter hashes could be designed.

xcaruso commented 1 year ago

@xcaruso You did not defined K. I guess you forgot K = A.fraction_field()...

Yes, thanks! I edited my message.