Ah, thank you so much!

Just to make sure that I understand the philosophy: if two elements are 
supposed to compare equal, they should have parents which can be coerced to 
a common parent, right?  For example, the following (which is current 
behaviour) is not really what we want:

sage: A = SetPartitions(3)([[1,2],[3]])
sage: B = SetPartition([[1,2],[3]])
sage: A == B
True
sage: coercion_model.common_parent(A, B)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [10], line 1
----> 1 coercion_model.common_parent(A, B)

File ~/sage-develop/src/sage/structure/coerce.pyx:1062, in 
sage.structure.coerce.CoercionModel.common_parent()
   1060         a = base.an_element() if isinstance(base, Parent) else 
base(1)
   1061         b = x.an_element() if isinstance(x, Parent) else x(1)
-> 1062         base = parent(self.canonical_coercion(a, b)[0])
   1063 return base
   1064 

File ~/sage-develop/src/sage/structure/coerce.pyx:1393, in 
sage.structure.coerce.CoercionModel.canonical_coercion()
   1391         self._record_exception()
   1392 
-> 1393 raise TypeError("no common canonical parent for objects with 
parents: '%s' and '%s'"%(xp, yp))
   1394 
   1395 

TypeError: no common canonical parent for objects with parents: 'Set 
partitions of {1, 2, 3}' and 'Set partitions'


On Sunday, 11 December 2022 at 20:03:26 UTC+1 Nils Bruin wrote:

> Once again:
>
> https://docs.python.org/3/reference/datamodel.html#object.__hash
>
> __eq__ and __hash__ are tied ad the hip: overriding one prevents 
> inheritance of the other.
>
> Python takes its contract "equality must imply identical hashes" a little 
> more seriously than sage, so Python doesn't allow the contract to be broken 
> by a careless partial override: rewriting one needs a rewrite of the other 
> as well.
>
> Whether __eq__ is the right hook to tap into I don't know. If those 
> classes participate in coercion, then absolutely not: they should implement 
> _eq_ or something like that and let coercion do its thing before presenting 
> elements to the class for comparison. But if these are really just 
> container types then a simple-minded `__eq__` implementation may be 
> sufficient (and perhaps there's nothing sensible to inherit from! I haven't 
> checked their MRO)
>
> On Sunday, 11 December 2022 at 02:19:41 UTC-8 axio...@yahoo.de wrote:
>
>> Help needed again.  I removed the (seemingly) useless overrides, but now 
>> SetPartition and DecoratedPermutation isn't hashable anymore.  Curiously, 
>> ParkingFunction is, and I don't see the difference.
>>
>> On Saturday, 10 December 2022 at 23:45:41 UTC+1 Martin R wrote:
>>
>>> https://trac.sagemath.org/ticket/34824 now removes the parent from the 
>>> hash, and all the overrides I could find.
>>> On Friday, 9 December 2022 at 23:03:38 UTC+1 Nils Bruin wrote:
>>>
>>>> On Friday, 9 December 2022 at 02:49:12 UTC-8 axio...@yahoo.de wrote:
>>>>
>>>>> Would it make sense to have a subclass, or perhaps an option to 
>>>>> ClonableArray.__init__, that determines whether or not to include the 
>>>>> parent into the hash?  The current behaviour seems rather error prone to 
>>>>> me.
>>>>>
>>>>
>>>> I think we've identified that there are definitely cases where having 
>>>> parent *not* included in the hash for certain versions of ClonableArray is 
>>>> beneficial. I'm not sure we have a convincing case where having the parent 
>>>> in the hash IS beneficial. A scenario where this would be the case would 
>>>> be 
>>>> if somewhere we end up with sets/dictionaries with loads of (non-equal) 
>>>> instances of ClonableArray such that tuple(...) hashes to the same value. 
>>>> I 
>>>> think it's unlikely that distinguishing on parent in the hash is ever a 
>>>> performance-essential feature. So it may be reasonable to change the hash 
>>>> function for all of them.
>>>>
>>>> If there are cases for both then the appropriate way is via overriding 
>>>> the hash on subclassing, not introducing extra flags on the init method: 
>>>> hash gets looked up via special method slots, so you should just make sure 
>>>> that the class has the right function registered. There's a mechanism for 
>>>> doing so: overriding methods in subclasses. 
>>>>
>>>> On the other hand, I am not sure whether GF(3)(4) == ZZ(4) is desirable.
>>>>>
>>>>
>>>> It's basically a corollary of being able to write GF(3)(1) + 1 . You'd 
>>>> end up with a system that is very painful to use interactively if you 
>>>> wouldn't allow for that (but, yes: coercion through quotient maps is 
>>>> definitely more problematic than through inclusions).
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sage-devel/23c2f366-77ad-41d3-820d-11819df20d4en%40googlegroups.com.

Reply via email to