# subsets of Set of unhashable items

Sage allows me to create a set:

S = Set( [factor(10), factor(15)] )


However, both S.subsets() and Subsets(S) produce:

TypeError: <class 'sage.structure.factorization_integer.IntegerFactorization'> is not hashable


What's wrong?

edit retag close merge delete

Sort by ยป oldest newest most voted

The problem comes from the fat that a Factorization object is not hashable:

sage: f = factor(15)
sage: f
3 * 5
sage: hash(f)
TypeError: <class 'sage.structure.factorization_integer.IntegerFactorization'> is not hashable


It should be (i will open a ticket for that).

You can workaround by replacing the factorization with a hashable equivalent : a tuple:

sage: t = tuple(f)
sage: t
((3, 1), (5, 1))
sage: hash(t)
8332132266671271694


You will be able to recover the factorization as follows:

sage: Factorization(t)
3 * 5
sage: Factorization(t) == f
True


So you can do something like:

sage: S = Set([tuple(factor(10)), tuple(factor(15))])
sage: S
{((2, 1), (5, 1)), ((3, 1), (5, 1))}

sage: len(S.subsets())
4
sage: S.subsets()[3]
{((2, 1), (5, 1)), ((3, 1), (5, 1))}

sage: S.subsets()[3][0]
((2, 1), (5, 1))
sage: Factorization(S.subsets()[3][0])
2 * 5


EDIT Be careful that the sign is lost when taking the tuple:

sage: a = -5
sage: a.factor()
-1 * 5
sage: tuple(a.factor())
((5, 1),)


EDIT Looking at the code, it is currently not possible to define a hash for Factorizaion objects since they are mutable (see, e.g. the simplify method that works in place).

more

I don't not worry much about Factorization here, but about behavior of Set in case of unhashable objects in general. On the other hand, it'd be nice to have Factorization hashable - please let me know the ticket number when you open it.

( 2022-05-02 17:53:28 +0100 )edit

The documentation for Setsays "Sets with unhashable objects work, but with less functionality". This is presumably part of that loss of functionality. https://doc.sagemath.org/html/en/refe...

( 2022-05-03 00:09:15 +0100 )edit