Opened 14 years ago
Closed 12 years ago
#5759 closed defect (fixed)
bug in divides
Reported by: | William Stein | Owned by: | William Stein |
---|---|---|---|
Priority: | major | Milestone: | sage-4.6 |
Component: | basic arithmetic | Keywords: | |
Cc: | Merged in: | sage-4.6.alpha3 | |
Authors: | Luis Felipe Tabera | Reviewers: | John Cremona |
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
The function "divides" does not work for generic commutative rings.
- it is not checked that the elements are in the same space, i.e.
Zmod(5)(1).divides(Zmod(2)(1)) is "True"
- No division by zero checking is done! This gives for example an error if you type
-> Zmod(2).zero_ideal() == Zmod(2).zero_ideal()
-> Zmod(2).zero_ideal() == Zmod(2).unit_ideal()
This patch should fix this. It may not be able to handle all cases but classes who need a more clever function should do their own implementation anyways.
Greetings, Kilian.
Attachments (3)
Change History (21)
Changed 14 years ago by
Attachment: | divides.patch added |
---|
comment:1 Changed 14 years ago by
Description: | modified (diff) |
---|---|
Priority: | minor → major |
comment:2 Changed 14 years ago by
Summary: | bug in divides → bug in divides [with patch, needs review] |
---|
comment:3 Changed 14 years ago by
Description: | modified (diff) |
---|
comment:4 Changed 14 years ago by
Description: | modified (diff) |
---|
comment:5 Changed 14 years ago by
Description: | modified (diff) |
---|
comment:6 Changed 14 years ago by
Owner: | changed from somebody to William Stein |
---|
Changed 14 years ago by
Attachment: | 5759-doctests.patch added |
---|
comment:7 Changed 14 years ago by
Summary: | bug in divides [with patch, needs review] → [with patch, needs review] bug in divides |
---|
comment:8 Changed 14 years ago by
Summary: | [with patch, needs review] bug in divides → [with patch, needs work] bug in divides |
---|
comment:9 Changed 14 years ago by
Summary: | [with patch, needs work] bug in divides → [with patch, needs work] class CommutativeRingElement |
---|
The whole divides function is broken (nearly irreparable) with the effect that "divides" failes or gives *wrong* answers if and only if the ring is no polynomial ring or ZZ (which have their own (buggy) implementation).
The reason is that not all commutative rings are euclidean domains and "modulo" operation does not do what it is supposed to do in general commutative rings, for example in finite integer rings: Zmod(12)(3) % Zmod(12)(4) gives Zmod(3)(0) (which is also broken, by the way).
The only correct behaviour would be:
- to raise a NotImplementedError? in element.py and let all subclasses implemenent their own divides.
or:
- define divides as "inclusion of ideals" and give errors if the subclasses can't check the inclusion of ideals.
Also: all doctests in element.py and other files are for polynomial rings only, with the effect that many functions in SAGE fail or give *wrong* answers if the ring is no polynomial ring.
Greetings, Kilian.
comment:10 Changed 14 years ago by
Summary: | [with patch, needs work] class CommutativeRingElement → [with patch, needs work] bug in divides |
---|
comment:11 Changed 13 years ago by
I would have thought that even in this generality (element of a commutative ring) it would be worth adding the following special cases:
- if self=1 return True
- if x =0 return True; else if self =0 return False
- if self.is_unit() return True
where in each case the test is wrapped in a try/except block so that if (for example) self.is_unit() is not implemented then it just passes. Finally, if none of the above works then default to code as it is now.
Any individual ring where the x%self computation will not work but where there is an easy alternative direct test (such as in Integers(n)) can have their own specific implementations. If there is any support for this I'm willing to try to do it.
comment:12 Changed 13 years ago by
Summary: | [with patch, needs work] bug in divides → [with patch, needs rebase] bug in divides |
---|
Note that #5347 (merged in 4.1.2.alpha2) fixes the easy cases I listed above. We still have
sage: Zmod(5)(1).divides(Zmod(2)(1)) True
but this looks fine to me:
sage: Zmod(2).zero_ideal() == Zmod(2).zero_ideal() True sage: Zmod(2).zero_ideal() == Zmod(2).unit_ideal() False
Hence the patches here need to be rebased and simplified to cater for the first one.
comment:13 Changed 13 years ago by
In fact the original patches can be discarded since they only fixed things that have been fixed anyway in #5347. What we do not have is a check the self and other are in "the same ring", which is not so obvious -- the simplest would be to throw an error if the parents were not identical, but that seems to harsh (it would cause 1.divides(1/2) to fail). Better would be to coerce into a common parent first -- the sort of thing which is done for __add___()
.
comment:14 Changed 13 years ago by
Report Upstream: | → N/A |
---|---|
Summary: | [with patch, needs rebase] bug in divides → bug in divides |
comment:15 Changed 12 years ago by
Status: | needs_work → needs_review |
---|
I add a patch to solve this problem. This patch is applied alone. Previous patches are discarded due to changes in the function during these months. See #5347
The algorithm first checks if parents coincide. If so, it runs the existing code. In other case, coerces both element to a common parent using the coercion model an runs the existing code on the coerced elements.
The patch works on 4.5.3
Changed 12 years ago by
Attachment: | trac-5759.patch added |
---|
comment:16 Changed 12 years ago by
Status: | needs_review → positive_review |
---|
The patch applies fine to 4.6.alpha1, and all test pass (I tested the whole sage library on account of earlier difficulties). No generic function can deliver everything, but this deals with simple generic cases, as the new doctests show.
comment:17 Changed 12 years ago by
Authors: | → Luis Felipe Tabera |
---|---|
Reviewers: | → John Cremona |
comment:18 Changed 12 years ago by
Merged in: | → sage-4.6.alpha3 |
---|---|
Resolution: | → fixed |
Status: | positive_review → closed |
This breaks a doctest somewhere else: