Skip to content

Commit

Permalink
Trac #13797: Fix overflow in hash and cmp() for LinearFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
vbraun committed Dec 5, 2012
1 parent 39b02df commit 4c85437
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/sage/numerical/linear_functions.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cdef class LinearFunction(ModuleElement):
cdef _richcmp(left, right, int op)
cpdef is_zero(self)
cpdef equals(LinearFunction left, LinearFunction right)
cdef int _cmp_c_impl(left, Element right) except -2

cdef class LinearConstraintsParent_class(Parent):
cdef LinearFunctionsParent_class _LF
Expand Down
49 changes: 46 additions & 3 deletions src/sage/numerical/linear_functions.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ include "../ext/stdsage.pxi"
include "../ext/interrupt.pxi"
include "../ext/cdefs.pxi"

cdef extern from "limits.h":
long LONG_MAX


from sage.structure.parent cimport Parent
from sage.structure.element cimport ModuleElement, Element
from sage.misc.cachefunc import cached_function
Expand Down Expand Up @@ -807,9 +811,9 @@ cdef class LinearFunction(ModuleElement):

def __hash__(self):
r"""
Defines a ``__hash__`` function
Return a hash.
EXAMPLE::
EXAMPLES::
sage: p = MixedIntegerLinearProgram()
sage: f = p({2 : 5, 3 : 2})
Expand All @@ -818,8 +822,47 @@ cdef class LinearFunction(ModuleElement):
sage: d = {}
sage: d[f] = 3
"""
return id(self)
# see _cmp_c_impl() if you want to change the hash function
return id(self) % LONG_MAX

def __cmp__(left, right):
"""
Part of the comparison framework.
EXAMPLES::
sage: p = MixedIntegerLinearProgram()
sage: f = p({2 : 5, 3 : 2})
sage: cmp(f, f)
0
"""
return (<Element>left)._cmp(right)

cdef int _cmp_c_impl(left, Element right) except -2:
"""
Implement comparison of two linear functions.
EXAMPLES::
sage: p = MixedIntegerLinearProgram()
sage: f = p({2 : 5, 3 : 2})
sage: cmp(f, f)
0
sage: abs(cmp(f, f+0)) # since we are comparing by id()
1
sage: abs(cmp(f, f+1))
1
sage: len(set([f, f]))
1
sage: len(set([f, f+0]))
2
sage: len(set([f, f+1]))
2
"""
# Note: if you want to implement smarter comparison, you also
# need to change __hash__(). The comparison function must
# satisfy cmp(x,y)==0 => hash(x)==hash(y)
return cmp(id(left), id(right))

#*****************************************************************************
#
Expand Down

0 comments on commit 4c85437

Please sign in to comment.