Skip to content

Commit

Permalink
Trac #34380: Free module does not correctly check domains
Browse files Browse the repository at this point in the history
Consider
{{{
sage: R.<x,y> = QQ[]
sage: I = R.ideal([x^2 - y^2 - 1])
sage: Q = R.quo(I)
sage: Q.is_integral_domain()
True
}}}
However
{{{
sage: Q2 = FreeModule(Q, 2)
sage: Q2.__class__.__mro__
(<class 'sage.modules.free_module.FreeModule_ambient_with_category'>,
 <class 'sage.modules.free_module.FreeModule_ambient'>,
 <class 'sage.modules.free_module.FreeModule_generic'>,
 <class 'sage.modules.free_module.Module_free_ambient'>,
 <class 'sage.modules.module.Module'>,
 ...
}}}
does not know it is a module over a domain. Contrast this with
{{{
sage: R2 = FreeModule(R, 2)
sage: R2.__class__.__mro__
(<class
'sage.modules.free_module.FreeModule_ambient_domain_with_category'>,
 <class 'sage.modules.free_module.FreeModule_ambient_domain'>,
 <class 'sage.modules.free_module.FreeModule_generic_domain'>,
 <class 'sage.modules.free_module.FreeModule_ambient'>,
 <class 'sage.modules.free_module.FreeModule_generic'>,
 <class 'sage.modules.free_module.Module_free_ambient'>,
 <class 'sage.modules.module.Module'>,
 ...
}}}
The issue is because the `try`-`except` block encapsulates too many
things:
{{{
sage: Q.is_field()
...
NotImplementedError:
}}}
causes it to bail out too early. We need to test more things.

URL: https://trac.sagemath.org/34380
Reported by: tscrim
Ticket author(s): Travis Scrimshaw
Reviewer(s): Kwankyu Lee
  • Loading branch information
Release Manager committed Aug 30, 2022
2 parents e889f0b + bb5e329 commit 349888c
Showing 1 changed file with 29 additions and 17 deletions.
46 changes: 29 additions & 17 deletions src/sage/modules/free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
import sage.rings.infinity
import sage.rings.integer
from sage.categories.principal_ideal_domains import PrincipalIdealDomains
from sage.categories.integral_domains import IntegralDomains
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
from sage.misc.randstate import current_randstate
from sage.structure.factory import UniqueFactory
Expand Down Expand Up @@ -236,6 +237,17 @@ def create_object(self, version, key):
sage: TestSuite(ZZ^6).run()
sage: TestSuite(RDF^3).run()
Check that :trac:`34380` is fixed::
sage: R.<x,y> = QQ[]
sage: Q = R.quo(R.ideal([x^2 - y^2 - 1]))
sage: Q.is_integral_domain()
True
sage: Q2 = FreeModule(Q, 2)
sage: from sage.modules.free_module import FreeModule_ambient_domain
sage: isinstance(Q2, FreeModule_ambient_domain)
True
"""
base_ring, rank, sparse, inner_product_matrix = key

Expand All @@ -254,29 +266,29 @@ def create_object(self, version, key):
"done from the right side.")
#raise TypeError, "The base_ring must be a commutative ring."

try:
if not sparse and isinstance(base_ring, sage.rings.abc.RealDoubleField):
return RealDoubleVectorSpace_class(rank)
if not sparse and isinstance(base_ring, sage.rings.abc.RealDoubleField):
return RealDoubleVectorSpace_class(rank)

elif not sparse and isinstance(base_ring, sage.rings.abc.ComplexDoubleField):
return ComplexDoubleVectorSpace_class(rank)
if not sparse and isinstance(base_ring, sage.rings.abc.ComplexDoubleField):
return ComplexDoubleVectorSpace_class(rank)

elif base_ring.is_field():
try:
if base_ring.is_field():
return FreeModule_ambient_field(base_ring, rank, sparse=sparse)
except NotImplementedError:
pass

elif base_ring in PrincipalIdealDomains():
return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
if base_ring in PrincipalIdealDomains():
return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)

elif isinstance(base_ring, sage.rings.abc.Order) \
and base_ring.is_maximal() and base_ring.class_number() == 1:
return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
if (isinstance(base_ring, sage.rings.abc.Order)
and base_ring.is_maximal() and base_ring.class_number() == 1):
return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)

elif isinstance(base_ring, ring.IntegralDomain) or base_ring.is_integral_domain():
return FreeModule_ambient_domain(base_ring, rank, sparse=sparse)
else:
return FreeModule_ambient(base_ring, rank, sparse=sparse)
except NotImplementedError:
return FreeModule_ambient(base_ring, rank, sparse=sparse)
if isinstance(base_ring, ring.IntegralDomain) or base_ring in IntegralDomains():
return FreeModule_ambient_domain(base_ring, rank, sparse=sparse)

return FreeModule_ambient(base_ring, rank, sparse=sparse)

FreeModuleFactory_with_standard_basis = FreeModuleFactory("FreeModule")

Expand Down

0 comments on commit 349888c

Please sign in to comment.