From bf9f3f4a8ca1fef0eaf4ffed224e8a85cb63ce93 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 16:52:10 +0100 Subject: [PATCH 01/16] move code from Spec to AffineScheme, deprecate is_Spec --- src/sage/schemes/generic/scheme.py | 295 +++++++++++++++++++++++++ src/sage/schemes/generic/spec.py | 332 ++--------------------------- 2 files changed, 307 insertions(+), 320 deletions(-) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 100026c16ed..adb921a2489 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -31,6 +31,8 @@ from sage.rings.commutative_ring import is_CommutativeRing from sage.rings.morphism import is_RingHomomorphism +from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal + def is_Scheme(x): """ Test whether ``x`` is a scheme. @@ -800,6 +802,299 @@ class AffineScheme(Scheme): """ An abstract affine scheme. """ + def __init__(self, R, S=None): + """ + Construct the spectrum of the ring ``R``. + + See :class:`Spec` for details. + + EXAMPLES:: + + sage: Spec(ZZ) + Spectrum of Integer Ring + """ + if not is_CommutativeRing(R): + raise TypeError, "R (=%s) must be a commutative ring"%R + self.__R = R + if not S is None: + if not is_CommutativeRing(S): + raise TypeError, "S (=%s) must be a commutative ring"%S + try: + S.hom(R) + except TypeError: + raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) + AffineScheme.__init__(self, S) + + def _cmp_(self, X): + """ + Compare ``self`` and ``X``. + + Spec's are compared with self using comparison of the + underlying rings. If X is not a Spec, then the result is + platform-dependent (either self < X or X < self, but never + self == X). + + INPUT: + + - ``X`` -- anything. + + OUTPUT: + + ``+1``, ``0``, or ``-1``. + + EXAMPLES:: + + sage: Spec(QQ) == Spec(QQ) + True + sage: Spec(QQ) == Spec(ZZ) + False + sage: Spec(QQ) == 5 + False + sage: Spec(GF(5)) < Spec(GF(7)) + True + sage: Spec(GF(7)) < Spec(GF(5)) + False + + TESTS:: + + sage: Spec(QQ).__cmp__(Spec(ZZ)) + 1 + """ + return cmp(self.__R, X.coordinate_ring()) + + def __hash__(self): + """ + Return the hash value. + + OUTPUT: + + A 32/64-bit hash value, depending on architecture. + + TESTS:: + + sage: hash(Spec(ZZ)) + -1667718069 # 32-bit + -5659298568736299957 # 64-bit + + sage: hash(Spec(QQ['x','y','z'])) + -804171295 # 32-bit + -4893002889606114847 # 64-bit + """ + # R is the only defining data, but we'd like to avoid collisions with it. + return hash("Spec") ^ hash(self.__R) + + def _repr_(self): + """ + Return a string representation of ``self``. + + OUTPUT: + + String. + + EXAMPLES:: + + sage: Spec(PolynomialRing(QQ, 3, 'x')) + Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field + + TESTS:: + + sage: Spec(PolynomialRing(QQ, 3, 'x'))._repr_() + 'Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field' + """ + return "Spectrum of %s"%self.__R + + def _latex_(self): + """ + LaTeX representation of this Spec. + + OUTPUT: + + String. + + EXAMPLES:: + + sage: S = Spec(PolynomialRing(ZZ, 2, 'x')) + sage: S + Spectrum of Multivariate Polynomial Ring in x0, x1 over Integer Ring + sage: S._latex_() + '\\mathrm{Spec}(\\Bold{Z}[x_{0}, x_{1}])' + """ + return "\\mathrm{Spec}(%s)" % self.__R._latex_() + + def __call__(self, x): + """ + Call syntax for Spec. + + INPUT/OUTPUT: + + The argument ``x`` must be one of the following: + + - a prime ideal of the coordinate ring; the output will + be the corresponding point of X + + - an element (or list of elements) of the coordinate ring + which generates a prime ideal; the output will be the + corresponding point of X + + - a ring or a scheme S; the output will be the set X(S) of + S-valued points on X + + EXAMPLES:: + + sage: S = Spec(ZZ) + sage: P = S(3); P + Point on Spectrum of Integer Ring defined by the Principal ideal (3) of Integer Ring + sage: type(P) + + sage: S(ZZ.ideal(next_prime(1000000))) + Point on Spectrum of Integer Ring defined by the Principal ideal (1000003) of Integer Ring + + sage: R. = QQ[] + sage: S = Spec(R) + sage: P = S(R.ideal(x, y, z)); P + Point on Spectrum of Multivariate Polynomial Ring + in x, y, z over Rational Field defined by the Ideal (x, y, z) + of Multivariate Polynomial Ring in x, y, z over Rational Field + + This indicates the fix of :trac:`12734`:: + sage: S = Spec(ZZ) + sage: S(ZZ) + Set of rational points of Spectrum of Integer Ring + sage: S(S) + Set of rational points of Spectrum of Integer Ring + """ + if is_CommutativeRing(x): + return self.point_homset(x) + from sage.schemes.all import is_Scheme + if is_Scheme(x): + return x.Hom(self) + + return SchemeTopologicalPoint_prime_ideal(self, x) + + def _an_element_(self): + r""" + Return an element of the spectrum of the ring. + + OUTPUT: + + A point of the affine scheme ``self``. + + EXAMPLES:: + + sage: Spec(QQ).an_element() + Point on Spectrum of Rational Field defined by the Principal ideal (0) of Rational Field + sage: Spec(ZZ).an_element() # random output + Point on Spectrum of Integer Ring defined by the Principal ideal (811) of Integer Ring + """ + if self.coordinate_ring() is ZZ: + from sage.rings.arith import random_prime + return self(random_prime(1000)) + return self(0) + + def coordinate_ring(self): + """ + Return the underlying ring of this scheme. + + OUTPUT: + + A commutative ring. + + EXAMPLES:: + + sage: Spec(QQ).coordinate_ring() + Rational Field + sage: Spec(PolynomialRing(QQ, 3, 'x')).coordinate_ring() + Multivariate Polynomial Ring in x0, x1, x2 over Rational Field + """ + return self.__R + + def is_noetherian(self): + """ + Test whether ``self`` is Noetherian. + + OUTPUT: + + Boolean. Return True if this scheme is Noetherian. + + EXAMPLES:: + + sage: Spec(ZZ).is_noetherian() + True + """ + return self.__R.is_noetherian() + + def dimension_absolute(self): + """ + Return the absolute dimension of this scheme. + + OUTPUT: + + Integer. + + EXAMPLES:: + + sage: S = Spec(ZZ) + sage: S.dimension_absolute() + 1 + sage: S.dimension() + 1 + """ + return self.__R.krull_dimension() + + dimension = dimension_absolute + + def dimension_relative(self): + """ + Return the relative dimension of this scheme over its base. + + OUTPUT: + + Integer. + + EXAMPLES:: + + sage: S = Spec(ZZ) + sage: S.dimension_relative() + 0 + """ + return self.__R.krull_dimension() - self.base_ring().krull_dimension() + + def base_extend(self, R): + """ + Extend the base ring/scheme. + + INPUT: + + - ``R`` -- an affine scheme or a commutative ring. + + EXAMPLES:: + + sage: Spec_ZZ = Spec(ZZ); Spec_ZZ + Spectrum of Integer Ring + sage: Spec_ZZ.base_extend(QQ) + Spectrum of Rational Field + """ + if is_CommutativeRing(R): + return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) + if not self.base_scheme() == R.base_scheme(): + raise ValueError('The new base scheme must be a scheme over the old base scheme.') + return Spec(self.coordinate_ring().base_extend(new_base.coordinate_ring()), + self.base_ring()) + + def _point_homset(self, *args, **kwds): + """ + Construct a point Hom-set. + + For internal use only. See :mod:`morphism` for more details. + + EXAMPLES:: + + sage: Spec(QQ)._point_homset(Spec(QQ), Spec(ZZ)) + Set of rational points of Spectrum of Integer Ring + """ + from sage.schemes.affine.affine_homset import SchemeHomset_points_spec + return SchemeHomset_points_spec(*args, **kwds) + def hom(self, x, Y=None): r""" Return the scheme morphism from ``self`` to ``Y`` defined by ``x``. diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index e31c698dc1e..48f014be7dc 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -1,5 +1,12 @@ """ -Spectrum of a ring as affine scheme. +The Spec functor + +AUTHORS: + +- William Stein + +- Peter Bruin (2014): rewrite Spec as a functor + """ #******************************************************************************* @@ -8,36 +15,13 @@ # http://www.gnu.org/licenses/ #******************************************************************************* -from sage.rings.commutative_ring import is_CommutativeRing from sage.rings.integer_ring import ZZ -from sage.schemes.generic.scheme import AffineScheme -from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal - - -def is_Spec(X): - """ - Test whether ``X`` is a Spec. - - INPUT: - - - ``X`` -- anything. - - OUTPUT: - - Boolean. +from sage.schemes.generic.scheme import AffineScheme, is_AffineScheme - EXAMPLES:: +from sage.misc.superseded import deprecated_function_alias - sage: from sage.schemes.generic.spec import is_Spec - sage: is_Spec(QQ^3) - False - sage: X = Spec(QQ); X - Spectrum of Rational Field - sage: is_Spec(X) - True - """ - return isinstance(X, Spec) +is_Spec = deprecated_function_alias(7946, is_AffineScheme) class Spec(AffineScheme): r""" @@ -103,298 +87,6 @@ class Spec(AffineScheme): sage: Spec(RDF,QQ).base_scheme() Spectrum of Rational Field """ - def __init__(self, R, S=None): - """ - Construct the spectrum of the ring ``R``. - - See :class:`Spec` for details. - - EXAMPLES:: - - sage: Spec(ZZ) - Spectrum of Integer Ring - """ - if not is_CommutativeRing(R): - raise TypeError, "R (=%s) must be a commutative ring"%R - self.__R = R - if not S is None: - if not is_CommutativeRing(S): - raise TypeError, "S (=%s) must be a commutative ring"%S - try: - S.hom(R) - except TypeError: - raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) - AffineScheme.__init__(self, S) - - def _cmp_(self, X): - """ - Compare ``self`` and ``X``. - - Spec's are compared with self using comparison of the - underlying rings. If X is not a Spec, then the result is - platform-dependent (either self < X or X < self, but never - self == X). - - INPUT: - - - ``X`` -- anything. - - OUTPUT: - - ``+1``, ``0``, or ``-1``. - - EXAMPLES:: - - sage: Spec(QQ) == Spec(QQ) - True - sage: Spec(QQ) == Spec(ZZ) - False - sage: Spec(QQ) == 5 - False - sage: Spec(GF(5)) < Spec(GF(7)) - True - sage: Spec(GF(7)) < Spec(GF(5)) - False - - TESTS:: - - sage: Spec(QQ).__cmp__(Spec(ZZ)) - 1 - """ - return cmp(self.__R, X.coordinate_ring()) - - def __hash__(self): - """ - Return the hash value. - - OUTPUT: - - A 32/64-bit hash value, depending on architecture. - - TESTS:: - - sage: hash(Spec(ZZ)) - -1667718069 # 32-bit - -5659298568736299957 # 64-bit - - sage: hash(Spec(QQ['x','y','z'])) - -804171295 # 32-bit - -4893002889606114847 # 64-bit - """ - # R is the only defining data, but we'd like to avoid collisions with it. - return hash("Spec") ^ hash(self.__R) - - def _repr_(self): - """ - Return a string representation of ``self``. - - OUTPUT: - - String. - - EXAMPLES:: - - sage: Spec(PolynomialRing(QQ, 3, 'x')) - Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - - TESTS:: - - sage: Spec(PolynomialRing(QQ, 3, 'x'))._repr_() - 'Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field' - """ - return "Spectrum of %s"%self.__R - - def _latex_(self): - """ - LaTeX representation of this Spec. - - OUTPUT: - - String. - - EXAMPLES:: - - sage: S = Spec(PolynomialRing(ZZ, 2, 'x')) - sage: S - Spectrum of Multivariate Polynomial Ring in x0, x1 over Integer Ring - sage: S._latex_() - '\\mathrm{Spec}(\\Bold{Z}[x_{0}, x_{1}])' - """ - return "\\mathrm{Spec}(%s)" % self.__R._latex_() - - def __call__(self, x): - """ - Call syntax for Spec. - - INPUT/OUTPUT: - - The argument ``x`` must be one of the following: - - - a prime ideal of the coordinate ring; the output will - be the corresponding point of X - - - an element (or list of elements) of the coordinate ring - which generates a prime ideal; the output will be the - corresponding point of X - - - a ring or a scheme S; the output will be the set X(S) of - S-valued points on X - - EXAMPLES:: - - sage: S = Spec(ZZ) - sage: P = S(3); P - Point on Spectrum of Integer Ring defined by the Principal ideal (3) of Integer Ring - sage: type(P) - - sage: S(ZZ.ideal(next_prime(1000000))) - Point on Spectrum of Integer Ring defined by the Principal ideal (1000003) of Integer Ring - - sage: R. = QQ[] - sage: S = Spec(R) - sage: P = S(R.ideal(x, y, z)); P - Point on Spectrum of Multivariate Polynomial Ring - in x, y, z over Rational Field defined by the Ideal (x, y, z) - of Multivariate Polynomial Ring in x, y, z over Rational Field - - This indicates the fix of :trac:`12734`:: - sage: S = Spec(ZZ) - sage: S(ZZ) - Set of rational points of Spectrum of Integer Ring - sage: S(S) - Set of rational points of Spectrum of Integer Ring - """ - if is_CommutativeRing(x): - return self.point_homset(x) - from sage.schemes.all import is_Scheme - if is_Scheme(x): - return x.Hom(self) - - return SchemeTopologicalPoint_prime_ideal(self, x) - - def _an_element_(self): - r""" - Return an element of the spectrum of the ring. - - OUTPUT: - - A point of the affine scheme ``self``. - - EXAMPLES:: - - sage: Spec(QQ).an_element() - Point on Spectrum of Rational Field defined by the Principal ideal (0) of Rational Field - sage: Spec(ZZ).an_element() # random output - Point on Spectrum of Integer Ring defined by the Principal ideal (811) of Integer Ring - """ - if self.coordinate_ring() is ZZ: - from sage.rings.arith import random_prime - return self(random_prime(1000)) - return self(0) - - def coordinate_ring(self): - """ - Return the underlying ring of this scheme. - - OUTPUT: - - A commutative ring. - - EXAMPLES:: - - sage: Spec(QQ).coordinate_ring() - Rational Field - sage: Spec(PolynomialRing(QQ, 3, 'x')).coordinate_ring() - Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - """ - return self.__R - - def is_noetherian(self): - """ - Test whether ``self`` is Noetherian. - - OUTPUT: - - Boolean. Return True if this scheme is Noetherian. - - EXAMPLES:: - - sage: Spec(ZZ).is_noetherian() - True - """ - return self.__R.is_noetherian() - - def dimension_absolute(self): - """ - Return the absolute dimension of this scheme. - - OUTPUT: - - Integer. - - EXAMPLES:: - - sage: S = Spec(ZZ) - sage: S.dimension_absolute() - 1 - sage: S.dimension() - 1 - """ - return self.__R.krull_dimension() - - dimension = dimension_absolute - - def dimension_relative(self): - """ - Return the relative dimension of this scheme over its base. - - OUTPUT: - - Integer. - - EXAMPLES:: - - sage: S = Spec(ZZ) - sage: S.dimension_relative() - 0 - """ - return self.__R.krull_dimension() - self.base_ring().krull_dimension() - - def base_extend(self, R): - """ - Extend the base ring/scheme. - - INPUT: - - - ``R`` -- an affine scheme or a commutative ring. - - EXAMPLES:: - - sage: Spec_ZZ = Spec(ZZ); Spec_ZZ - Spectrum of Integer Ring - sage: Spec_ZZ.base_extend(QQ) - Spectrum of Rational Field - """ - if is_CommutativeRing(R): - return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) - if not self.base_scheme() == R.base_scheme(): - raise ValueError('The new base scheme must be a scheme over the old base scheme.') - return Spec(self.coordinate_ring().base_extend(new_base.coordinate_ring()), - self.base_ring()) - - def _point_homset(self, *args, **kwds): - """ - Construct a point Hom-set. - - For internal use only. See :mod:`morphism` for more details. - - EXAMPLES:: - - sage: Spec(QQ)._point_homset(Spec(QQ), Spec(ZZ)) - Set of rational points of Spectrum of Integer Ring - """ - from sage.schemes.affine.affine_homset import SchemeHomset_points_spec - return SchemeHomset_points_spec(*args, **kwds) - + pass SpecZ = Spec(ZZ) From 9363fd8a2cc7ac865c19b8546d79da7e2becd62e Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 16:58:02 +0100 Subject: [PATCH 02/16] replace is_CommutativeRing() by category membership, fix handling of ideals --- src/sage/schemes/generic/point.py | 11 ++++++----- src/sage/schemes/generic/scheme.py | 18 +++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/generic/point.py b/src/sage/schemes/generic/point.py index 28c6142a2bd..f6679ae135b 100644 --- a/src/sage/schemes/generic/point.py +++ b/src/sage/schemes/generic/point.py @@ -120,10 +120,10 @@ def __init__(self, S, P, check=False): """ INPUT: + - ``S`` -- an affine scheme - - ``S`` - an affine scheme - - - ``P`` - a prime ideal of the coordinate ring of S + - ``P`` -- a prime ideal of the coordinate ring of `S`, or + anything that can be converted into such an ideal TESTS:: @@ -146,8 +146,9 @@ def __init__(self, S, P, check=False): Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field """ R = S.coordinate_ring() - from sage.rings.ideal import Ideal - P = Ideal(R, P) + from sage.rings.ideal import is_Ideal + if not (is_Ideal(P) and P.ring() is R): + P = R.ideal(P) # ideally we would have check=True by default, but # unfortunately is_prime() is only implemented in a small # number of cases diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index adb921a2489..f10e360ad50 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -645,7 +645,7 @@ def hom(self, x, Y=None, check=True): return self.Hom(x).natural_map() else: raise TypeError, "unable to determine codomain" - return self.Hom(Y)(x, check) + return self.Hom(Y)(x, check=check) def _Hom_(self, Y, category=None, check=True): """ @@ -813,15 +813,14 @@ def __init__(self, R, S=None): sage: Spec(ZZ) Spectrum of Integer Ring """ - if not is_CommutativeRing(R): + from sage.categories.commutative_rings import CommutativeRings + if not R in CommutativeRings(): raise TypeError, "R (=%s) must be a commutative ring"%R self.__R = R if not S is None: - if not is_CommutativeRing(S): + if not S in CommutativeRings(): raise TypeError, "S (=%s) must be a commutative ring"%S - try: - S.hom(R) - except TypeError: + if not R.has_coerce_map_from(S): raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) AffineScheme.__init__(self, S) @@ -988,8 +987,8 @@ def _an_element_(self): """ if self.coordinate_ring() is ZZ: from sage.rings.arith import random_prime - return self(random_prime(1000)) - return self(0) + return self(ZZ.ideal(random_prime(1000))) + return self(self.coordinate_ring().zero_ideal()) def coordinate_ring(self): """ @@ -1074,7 +1073,8 @@ def base_extend(self, R): sage: Spec_ZZ.base_extend(QQ) Spectrum of Rational Field """ - if is_CommutativeRing(R): + from sage.categories.commutative_rings import CommutativeRings + if R in CommutativeRings(): return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): raise ValueError('The new base scheme must be a scheme over the old base scheme.') From 9c3008e48a59abbc73f5c5da1206056854cd0185 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 17:04:47 +0100 Subject: [PATCH 03/16] replace Spec by AffineScheme where appropriate --- src/sage/categories/schemes.py | 4 +-- src/sage/schemes/generic/homset.py | 29 +++++++++---------- src/sage/schemes/generic/scheme.py | 23 ++++++--------- .../hyperelliptic_curves/jacobian_homset.py | 4 +-- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/sage/categories/schemes.py b/src/sage/categories/schemes.py index f72c07bdf61..126cc5f76f9 100644 --- a/src/sage/categories/schemes.py +++ b/src/sage/categories/schemes.py @@ -195,8 +195,8 @@ def _repr_object_names(self): Category of schemes over Integer Ring """ # To work around the name of the class (schemes_over_base) - from sage.schemes.generic.spec import is_Spec - if is_Spec(self.base_scheme()): + from sage.schemes.generic.scheme import is_AffineScheme + if is_AffineScheme(self.base_scheme()): return "schemes over %s" % self.base_scheme().coordinate_ring() else: return "schemes over %s" % self.base_scheme() diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index c224832eb3c..8404e990195 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -47,9 +47,7 @@ from sage.rings.finite_rings.constructor import is_FiniteField from sage.rings.commutative_ring import is_CommutativeRing - -from sage.schemes.generic.scheme import is_Scheme -from sage.schemes.generic.spec import Spec, is_Spec +from sage.schemes.generic.scheme import AffineScheme, is_AffineScheme from sage.schemes.generic.morphism import ( SchemeMorphism, SchemeMorphism_structure_map, @@ -160,19 +158,18 @@ def create_key_and_extra_args(self, X, Y, category=None, base=ZZ, 'X': Affine Space of dimension 3 over Rational Field, 'base_ring': Integer Ring, 'check': False} """ - if not is_Scheme(X) and is_CommutativeRing(X): - X = Spec(X) - if not is_Scheme(Y) and is_CommutativeRing(Y): - Y = Spec(Y) - if is_Spec(base): + if is_CommutativeRing(X): + X = AffineScheme(X) + if is_CommutativeRing(Y): + Y = AffineScheme(Y) + if is_AffineScheme(base): base_spec = base base_ring = base.coordinate_ring() elif is_CommutativeRing(base): - base_spec = Spec(base) + base_spec = AffineScheme(base) base_ring = base else: - raise ValueError( - 'The base must be a commutative ring or its spectrum.') + raise ValueError('base must be a commutative ring or its spectrum') if not category: from sage.categories.schemes import Schemes category = Schemes(base_spec) @@ -210,7 +207,7 @@ def create_object(self, version, key, **extra_args): X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') - if is_Spec(X): + if is_AffineScheme(X): return Y._point_homset(X, Y, category=category, base=base_ring, **extra_args) try: return X._homset(X, Y, category=category, base=base_ring, **extra_args) @@ -329,7 +326,7 @@ def natural_map(self): """ X = self.domain() Y = self.codomain() - if is_Spec(Y) and Y.coordinate_ring() == X.base_ring(): + if is_AffineScheme(Y) and Y.coordinate_ring() == X.base_ring(): return SchemeMorphism_structure_map(self) raise NotImplementedError @@ -440,7 +437,7 @@ def __init__(self, X, Y, category=None, check=True, base=ZZ): sage: SchemeHomset_points(Spec(QQ), AffineSpace(ZZ,2)) Set of rational points of Affine Space of dimension 2 over Rational Field """ - if check and not is_Spec(X): + if check and not is_AffineScheme(X): raise ValueError('The domain must be an affine scheme.') SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base) @@ -549,8 +546,8 @@ def value_ring(self): Rational Field """ dom = self.domain() - if not is_Spec(dom): - raise ValueError("value rings are defined for Spec domains only!") + if not is_AffineScheme(dom): + raise ValueError("value rings are defined for affine domains only") return dom.coordinate_ring() def cardinality(self): diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index f10e360ad50..7682c45f4df 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -103,7 +103,6 @@ def __init__(self, X=None, category=None): sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", ... "_test_some_elements", "_test_category"]) # See #7946 """ - from sage.schemes.generic.spec import is_Spec from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: @@ -333,8 +332,7 @@ def point_homset(self, S=None): """ if S is None: S = self.base_ring() - from sage.schemes.generic.spec import Spec - SpecS = Spec(S, self.base_ring()) + SpecS = AffineScheme(S, self.base_ring()) from sage.schemes.generic.homset import SchemeHomset return SchemeHomset(SpecS, self) @@ -478,8 +476,7 @@ def base_scheme(self): if hasattr(self, '_base_morphism'): self._base_scheme = self._base_morphism.codomain() elif hasattr(self, '_base_ring'): - from sage.schemes.generic.spec import Spec - self._base_scheme = Spec(self._base_ring) + self._base_scheme = AffineScheme(self._base_ring) else: from sage.schemes.generic.spec import SpecZ self._base_scheme = SpecZ @@ -514,12 +511,12 @@ def base_morphism(self): return self._base_morphism except AttributeError: from sage.categories.schemes import Schemes - from sage.schemes.generic.spec import Spec, SpecZ + from sage.schemes.generic.spec import SpecZ SCH = Schemes() if hasattr(self, '_base_scheme'): self._base_morphism = self.Hom(self._base_scheme, category=SCH).natural_map() elif hasattr(self, '_base_ring'): - self._base_morphism = self.Hom(Spec(self._base_ring), category=SCH).natural_map() + self._base_morphism = self.Hom(AffineScheme(self._base_ring), category=SCH).natural_map() else: self._base_morphism = self.Hom(SpecZ, category=SCH).natural_map() return self._base_morphism @@ -1075,11 +1072,11 @@ def base_extend(self, R): """ from sage.categories.commutative_rings import CommutativeRings if R in CommutativeRings(): - return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) + return AffineScheme(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): raise ValueError('The new base scheme must be a scheme over the old base scheme.') - return Spec(self.coordinate_ring().base_extend(new_base.coordinate_ring()), - self.base_ring()) + return AffineScheme(self.coordinate_ring().base_extend(new_base.coordinate_ring()), + self.base_ring()) def _point_homset(self, *args, **kwds): """ @@ -1146,9 +1143,7 @@ def hom(self, x, Y=None): """ if is_Scheme(x): return self.Hom(x).natural_map() - if Y is None: - if is_RingHomomorphism(x): - import spec - Y = spec.Spec(x.domain()) + if Y is None and is_RingHomomorphism(x): + Y = AffineScheme(x.domain()) return Scheme.hom(self, x, Y) diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index 2be13fdbc95..bfa5e07a21d 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -54,7 +54,6 @@ from sage.schemes.generic.homset import SchemeHomset_points from sage.schemes.generic.morphism import is_SchemeMorphism -from sage.schemes.generic.spec import Spec, is_Spec from jacobian_morphism import JacobianMorphism_divisor_class_field class JacobianHomset_divisor_classes(SchemeHomset_points): @@ -170,8 +169,9 @@ def value_ring(self): """ Returns S for a homset X(T) where T = Spec(S). """ + from sage.schemes.generic.scheme import is_AffineScheme T = self.domain() - if is_Spec(T): + if is_AffineScheme(T): return T.coordinate_ring() else: raise TypeError, "Domain of argument must be of the form Spec(S)." From ff922919be3953efeaf874f5d9d6d3a462491a50 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 17:12:05 +0100 Subject: [PATCH 04/16] fix __init__ --- src/sage/schemes/affine/affine_space.py | 1 + src/sage/schemes/generic/scheme.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index b58f9d46148..7c78984e3aa 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -163,6 +163,7 @@ def __init__(self, n, R, names): names = normalize_names(n, names) AmbientSpace.__init__(self, n, R) self._assign_names(names) + AffineScheme.__init__(self, self.coordinate_ring(), R) def __iter__(self): """ diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 7682c45f4df..4c41273314d 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -799,7 +799,7 @@ class AffineScheme(Scheme): """ An abstract affine scheme. """ - def __init__(self, R, S=None): + def __init__(self, R, S=None, category=None): """ Construct the spectrum of the ring ``R``. @@ -819,7 +819,7 @@ def __init__(self, R, S=None): raise TypeError, "S (=%s) must be a commutative ring"%S if not R.has_coerce_map_from(S): raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) - AffineScheme.__init__(self, S) + Scheme.__init__(self, S, category=category) def _cmp_(self, X): """ From 86a2b117969a7df9155650d3d2fe6736403497d3 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 19:58:42 +0100 Subject: [PATCH 05/16] distinguish "point homsets" and "normal homsets" using flag --- src/sage/schemes/generic/homset.py | 13 +++++++------ src/sage/schemes/generic/scheme.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 8404e990195..7ded50dc0fe 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -121,7 +121,7 @@ class SchemeHomsetFactory(UniqueFactory): """ def create_key_and_extra_args(self, X, Y, category=None, base=ZZ, - check=True): + check=True, as_point_homset=False): """ Create a key that uniquely determines the Hom-set. @@ -152,7 +152,7 @@ def create_key_and_extra_args(self, X, Y, category=None, base=ZZ, sage: SHOMfactory = SchemeHomsetFactory('test') sage: key, extra = SHOMfactory.create_key_and_extra_args(A3,A2,check=False) sage: key - (..., ..., Category of schemes over Integer Ring) + (..., ..., Category of schemes over Integer Ring, False) sage: extra {'Y': Affine Space of dimension 2 over Rational Field, 'X': Affine Space of dimension 3 over Rational Field, @@ -173,7 +173,7 @@ def create_key_and_extra_args(self, X, Y, category=None, base=ZZ, if not category: from sage.categories.schemes import Schemes category = Schemes(base_spec) - key = tuple([id(X), id(Y), category]) + key = tuple([id(X), id(Y), category, as_point_homset]) extra = {'X':X, 'Y':Y, 'base_ring':base_ring, 'check':check} return key, extra @@ -197,17 +197,18 @@ def create_object(self, version, key, **extra_args): True sage: from sage.schemes.generic.homset import SchemeHomsetFactory sage: SHOMfactory = SchemeHomsetFactory('test') - sage: SHOMfactory.create_object(0, [id(A3),id(A2),A3.category()], check=True, - ... X=A3, Y=A2, base_ring=QQ) + sage: SHOMfactory.create_object(0, [id(A3), id(A2), A3.category(), False], + ....: check=True, X=A3, Y=A2, base_ring=QQ) Set of morphisms From: Affine Space of dimension 3 over Rational Field To: Affine Space of dimension 2 over Rational Field """ category = key[2] + as_point_homset = key[3] X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') - if is_AffineScheme(X): + if as_point_homset: return Y._point_homset(X, Y, category=category, base=base_ring, **extra_args) try: return X._homset(X, Y, category=category, base=base_ring, **extra_args) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 4c41273314d..16b3c85ff3e 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -334,7 +334,7 @@ def point_homset(self, S=None): S = self.base_ring() SpecS = AffineScheme(S, self.base_ring()) from sage.schemes.generic.homset import SchemeHomset - return SchemeHomset(SpecS, self) + return SchemeHomset(SpecS, self, as_point_homset=True) def point(self, v, check=True): """ From 631092f202b0e042f755545f91882440704b8cb6 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 20:16:28 +0100 Subject: [PATCH 06/16] fix AffineScheme call syntax --- src/sage/schemes/generic/scheme.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 16b3c85ff3e..9d793d22d9e 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -31,8 +31,6 @@ from sage.rings.commutative_ring import is_CommutativeRing from sage.rings.morphism import is_RingHomomorphism -from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal - def is_Scheme(x): """ Test whether ``x`` is a scheme. @@ -917,7 +915,7 @@ def _latex_(self): """ return "\\mathrm{Spec}(%s)" % self.__R._latex_() - def __call__(self, x): + def __call__(self, *args): """ Call syntax for Spec. @@ -928,17 +926,13 @@ def __call__(self, x): - a prime ideal of the coordinate ring; the output will be the corresponding point of X - - an element (or list of elements) of the coordinate ring - which generates a prime ideal; the output will be the - corresponding point of X - - a ring or a scheme S; the output will be the set X(S) of S-valued points on X EXAMPLES:: sage: S = Spec(ZZ) - sage: P = S(3); P + sage: P = S(ZZ.ideal(3)); P Point on Spectrum of Integer Ring defined by the Principal ideal (3) of Integer Ring sage: type(P) @@ -959,13 +953,14 @@ def __call__(self, x): sage: S(S) Set of rational points of Spectrum of Integer Ring """ - if is_CommutativeRing(x): - return self.point_homset(x) - from sage.schemes.all import is_Scheme - if is_Scheme(x): - return x.Hom(self) + if len(args) == 1: + from sage.rings.ideal import is_Ideal + x = args[0] + if is_Ideal(x) and x.ring() is self.coordinate_ring(): + from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal + return SchemeTopologicalPoint_prime_ideal(self, x) - return SchemeTopologicalPoint_prime_ideal(self, x) + return super(AffineScheme, self).__call__(*args) def _an_element_(self): r""" From 1978bf448a25ff572735527db8e6bb380e91d955 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 20:59:24 +0100 Subject: [PATCH 07/16] fix doctest failures --- src/sage/schemes/generic/homset.py | 4 +++- src/sage/schemes/generic/scheme.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 7ded50dc0fe..54ae0a773fc 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -352,7 +352,9 @@ def _element_constructor_(self, x, check=True): To: Rational Field sage: H = Hom(Spec(QQ, ZZ), Spec(ZZ)); H - Set of rational points of Spectrum of Integer Ring + Set of morphisms + From: Spectrum of Rational Field + To: Spectrum of Integer Ring sage: phi = H(f); phi Affine Scheme morphism: diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 9d793d22d9e..bb330352b92 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -665,19 +665,21 @@ def _Hom_(self, Y, category=None, check=True): sage: P = ProjectiveSpace(ZZ, 3) sage: S = Spec(ZZ) sage: S._Hom_(P) - Set of rational points of Projective Space of dimension 3 over Integer Ring + Set of morphisms + From: Spectrum of Integer Ring + To: Projective Space of dimension 3 over Integer Ring TESTS:: sage: S._Hom_(P).__class__ - + sage: E = EllipticCurve('37a1') sage: Hom(E, E).__class__ sage: Hom(Spec(ZZ), Spec(ZZ)).__class__ - + """ from sage.schemes.generic.homset import SchemeHomset return SchemeHomset(self, Y, category=category, check=check) @@ -950,8 +952,14 @@ def __call__(self, *args): sage: S = Spec(ZZ) sage: S(ZZ) Set of rational points of Spectrum of Integer Ring + + Note the difference between the previous example and the + following one:: + sage: S(S) - Set of rational points of Spectrum of Integer Ring + Set of morphisms + From: Spectrum of Integer Ring + To: Spectrum of Integer Ring """ if len(args) == 1: from sage.rings.ideal import is_Ideal From 5003e6fa88d5d028928d17cce32e4daaadffc9c1 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 23:50:39 +0100 Subject: [PATCH 08/16] rewrite Spec as a functor, fix pickling and related things --- src/sage/schemes/generic/homset.py | 20 +++++++-- src/sage/schemes/generic/scheme.py | 11 +++++ src/sage/schemes/generic/spec.py | 67 +++++++++++++++++++++++++----- 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 54ae0a773fc..9018daff827 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -204,7 +204,7 @@ def create_object(self, version, key, **extra_args): To: Affine Space of dimension 2 over Rational Field """ category = key[2] - as_point_homset = key[3] + as_point_homset = key[3] if len(key) >= 4 else False X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') @@ -264,8 +264,8 @@ def __reduce__(self): sage: loads(Hom.dumps()) == Hom True """ - #return SchemeHomset.reduce_data(self) - return SchemeHomset, (self.domain(), self.codomain(), self.homset_category()) + return SchemeHomset, (self.domain(), self.codomain(), self.homset_category(), + self.base_ring(), False, False) def __call__(self, *args, **kwds): r""" @@ -444,6 +444,20 @@ def __init__(self, X, Y, category=None, check=True, base=ZZ): raise ValueError('The domain must be an affine scheme.') SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base) + def __reduce__(self): + """ + Used in pickling. + + EXAMPLES:: + + sage: A2 = AffineSpace(QQ,2) + sage: Hom = A2(QQ) + sage: loads(Hom.dumps()) == Hom + True + """ + return SchemeHomset, (self.domain(), self.codomain(), self.homset_category(), + self.base_ring(), False, True) + def _element_constructor_(self, *v, **kwds): """ The element contstructor. diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index bb330352b92..c757ce8ff13 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -821,6 +821,17 @@ def __init__(self, R, S=None, category=None): raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) Scheme.__init__(self, S, category=category) + def __setstate__(self, state): + """ + Needed to unpickle old Spec objects. + + The name-mangled attribute ``__R`` used to be in a class + called ``Spec``; we have to translate this mangled name. + """ + if '_Spec__R' in state: + state['_AffineScheme__R'] = state.pop('_Spec__R') + super(AffineScheme, self).__setstate__(state) + def _cmp_(self, X): """ Compare ``self`` and ``X``. diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index 48f014be7dc..c219c54f872 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -3,7 +3,7 @@ AUTHORS: -- William Stein +- William Stein (2006): initial implementation - Peter Bruin (2014): rewrite Spec as a functor @@ -15,15 +15,12 @@ # http://www.gnu.org/licenses/ #******************************************************************************* +from sage.categories.functor import Functor from sage.rings.integer_ring import ZZ - from sage.schemes.generic.scheme import AffineScheme, is_AffineScheme +from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.superseded import deprecated_function_alias - -is_Spec = deprecated_function_alias(7946, is_AffineScheme) - -class Spec(AffineScheme): +def Spec(R, S=None): r""" The spectrum of a commutative ring, as a scheme. @@ -64,12 +61,11 @@ class Spec(AffineScheme): sage: Spec(5) Traceback (most recent call last): ... - TypeError: R (=5) must be a commutative ring + TypeError: x (=5) is not in Category of commutative rings sage: Spec(FreeAlgebra(QQ,2, 'x')) Traceback (most recent call last): ... - TypeError: R (=Free Algebra on 2 generators (x0, x1) over - Rational Field) must be a commutative ring + TypeError: x (=Free Algebra on 2 generators (x0, x1) over Rational Field) is not in Category of commutative rings TESTS:: @@ -87,6 +83,55 @@ class Spec(AffineScheme): sage: Spec(RDF,QQ).base_scheme() Spectrum of Rational Field """ - pass + return SpecFunctor(S)(R) + +class SpecFunctor(Functor, UniqueRepresentation): + """ + TODO + """ + def __init__(self, base_ring=None): + """ + TODO + """ + from sage.categories.all import CommutativeAlgebras, CommutativeRings, Schemes + + if base_ring is None: + domain = CommutativeRings() + codomain = Schemes() + elif base_ring in CommutativeRings(): + # We would like to use CommutativeAlgebras(base_ring) as + # the domain; we use CommutativeRings() instead because + # currently many algebras are not yet considered to be in + # CommutativeAlgebras(base_ring) by the category framework. + domain = CommutativeRings() + codomain = Schemes(AffineScheme(base_ring)) + else: + raise TypeError('base object (= %s) must be a commutative ring or a scheme') + self._base_ring = base_ring + super(SpecFunctor, self).__init__(domain, codomain) + + def _apply_functor(self, A): + """ + TODO + """ + return AffineScheme(A, self._base_ring) + + def _apply_functor_to_morphism(self, f): + """ + TODO + """ + A = f.domain() + B = f.codomain() + return self(B).hom(f, self(A)) + SpecZ = Spec(ZZ) + + +# Compatibility with older versions of this module + +from sage.misc.superseded import deprecated_function_alias +is_Spec = deprecated_function_alias(7946, is_AffineScheme) + +from sage.structure.sage_object import register_unpickle_override +register_unpickle_override('sage.schemes.generic.spec', 'Spec', AffineScheme) From 68f25537a7a07b536af33e33b2d5eab91cfc0d82 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 12 Apr 2014 20:37:10 +0100 Subject: [PATCH 09/16] add documentation for AffineScheme, Spec, SpecFunctor add methods _repr_() and _latex_() to SpecFunctor --- src/sage/schemes/generic/scheme.py | 68 ++++++++++++++++++---- src/sage/schemes/generic/spec.py | 90 ++++++++++++++++++++++++------ 2 files changed, 131 insertions(+), 27 deletions(-) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index c757ce8ff13..f83dbc26b8a 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -797,18 +797,66 @@ def is_AffineScheme(x): class AffineScheme(Scheme): """ - An abstract affine scheme. + Class for general affine schemes. + + TESTS:: + + sage: from sage.schemes.generic.scheme import AffineScheme + sage: A = QQ['t'] + sage: X_abs = AffineScheme(A); X_abs + Spectrum of Univariate Polynomial Ring in t over Rational Field + sage: X_rel = AffineScheme(A, QQ); X_rel + Spectrum of Univariate Polynomial Ring in t over Rational Field + + sage: X_abs == X_rel + True + sage: X_abs.base_ring() + Integer Ring + sage: X_rel.base_ring() + Rational Field + + .. SEEALSO:: + + For affine spaces over a base ring and subschemes thereof, see + :class:`sage.schemes.generic.algebraic_scheme.AffineSpace`. + """ def __init__(self, R, S=None, category=None): """ - Construct the spectrum of the ring ``R``. + Construct the affine scheme with coordinate ring `R`. + + INPUT: - See :class:`Spec` for details. + - ``R`` -- commutative ring + + - ``S`` -- (optional) commutative ring admitting a natural map + to ``R`` + + OUTPUT: + + The spectrum of `R`, i.e. the unique affine scheme with + coordinate ring `R` as a scheme over the base ring `S`. EXAMPLES:: - sage: Spec(ZZ) + sage: from sage.schemes.generic.scheme import AffineScheme + sage: A. = PolynomialRing(QQ) + sage: X = AffineScheme(A, QQ) + sage: X + Spectrum of Multivariate Polynomial Ring in x, y over Rational Field + sage: X.category() + Category of schemes over Rational Field + + The standard way to construct an affine scheme is to use the + :func:`~sage.schemes.generic.spec.Spec` functor:: + + sage: S = Spec(ZZ) + sage: S Spectrum of Integer Ring + sage: S.category() + Category of Schemes + sage: type(S) + """ from sage.categories.commutative_rings import CommutativeRings if not R in CommutativeRings(): @@ -836,10 +884,8 @@ def _cmp_(self, X): """ Compare ``self`` and ``X``. - Spec's are compared with self using comparison of the - underlying rings. If X is not a Spec, then the result is - platform-dependent (either self < X or X < self, but never - self == X). + Affine schemes are compared using comparison of the + underlying rings. INPUT: @@ -896,7 +942,7 @@ def _repr_(self): OUTPUT: - String. + A string. EXAMPLES:: @@ -912,11 +958,11 @@ def _repr_(self): def _latex_(self): """ - LaTeX representation of this Spec. + Return a LaTeX representation of ``self``. OUTPUT: - String. + A string. EXAMPLES:: diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index c219c54f872..3ae5c475090 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -22,20 +22,17 @@ def Spec(R, S=None): r""" - The spectrum of a commutative ring, as a scheme. + Apply the Spec functor to `R`. - .. note:: + INPUT: - Calling ``Spec(R)`` twice produces two distinct (but equal) - schemes, which is important for gluing to construct more - general schemes. + - ``R`` -- either a commutative ring or a ring homomorphism - INPUT: + - ``S`` -- a commutative ring (optional), the base ring - - ``R`` -- a commutative ring. + OUTPUT: - - ``S`` -- a commutative ring (optional, default:`\ZZ`). The base - ring. + - ``AffineScheme`` -- the affine scheme `\text{Spec}(R)` EXAMPLES:: @@ -47,8 +44,9 @@ def Spec(R, S=None): Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field sage: X = Spec(PolynomialRing(GF(49,'a'), 3, 'x')); X Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Finite Field in a of size 7^2 - sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", - ... "_test_some_elements"]) + sage: TestSuite(X).run(skip=["_test_an_element", "_test_elements", "_test_some_elements"]) + + Applying ``Spec`` twice gives equal but non-identical output:: sage: A = Spec(ZZ); B = Spec(ZZ) sage: A is B @@ -87,11 +85,18 @@ def Spec(R, S=None): class SpecFunctor(Functor, UniqueRepresentation): """ - TODO + The Spec functor. """ def __init__(self, base_ring=None): """ - TODO + EXAMPLE:: + + sage: from sage.schemes.generic.spec import SpecFunctor + sage: SpecFunctor() + Spec functor from Category of commutative rings to Category of Schemes + sage: SpecFunctor(QQ) + Spec functor from Category of commutative rings to Category of schemes over Rational Field + """ from sage.categories.all import CommutativeAlgebras, CommutativeRings, Schemes @@ -106,19 +111,72 @@ def __init__(self, base_ring=None): domain = CommutativeRings() codomain = Schemes(AffineScheme(base_ring)) else: - raise TypeError('base object (= %s) must be a commutative ring or a scheme') + raise TypeError('base (= %s) must be a commutative ring') self._base_ring = base_ring super(SpecFunctor, self).__init__(domain, codomain) + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLE:: + + sage: from sage.schemes.generic.spec import SpecFunctor + sage: SpecFunctor(QQ) + Spec functor from Category of commutative rings to Category of schemes over Rational Field + + """ + return 'Spec functor from %s to %s' % (self.domain(), self.codomain()) + + def _latex_(self): + r""" + Return a LaTeX representation of ``self``. + + EXAMPLE:: + + sage: from sage.schemes.generic.spec import SpecFunctor + sage: latex(SpecFunctor()) + \mathrm{Spec}\colon \mathbf{CommutativeRings} \longrightarrow \mathbf{Schemes} + + """ + return (r'\mathrm{Spec}\colon %s \longrightarrow %s' + % (self.domain()._latex_(), self.codomain()._latex_())) + def _apply_functor(self, A): """ - TODO + Apply the Spec functor to the commutative ring ``A``. + + EXAMPLE:: + + sage: from sage.schemes.generic.spec import SpecFunctor + sage: F = SpecFunctor() + sage: F(RR) + Spectrum of Real Field with 53 bits of precision + """ return AffineScheme(A, self._base_ring) def _apply_functor_to_morphism(self, f): """ - TODO + Apply the Spec functor to the ring homomorphism ``f``. + + EXAMPLE:: + + sage: from sage.schemes.generic.spec import SpecFunctor + sage: F = SpecFunctor(GF(7)) + sage: A. = GF(7)[] + sage: B. = GF(7)[] + sage: f = A.hom((t^2, t^3)) + sage: Spec(f) + Affine Scheme morphism: + From: Spectrum of Univariate Polynomial Ring in t over Finite Field of size 7 + To: Spectrum of Multivariate Polynomial Ring in x, y over Finite Field of size 7 + Defn: Ring morphism: + From: Multivariate Polynomial Ring in x, y over Finite Field of size 7 + To: Univariate Polynomial Ring in t over Finite Field of size 7 + Defn: x |--> t^2 + y |--> t^3 + """ A = f.domain() B = f.codomain() From 9d4ddc6bbd7a98e8312d93e6c85a44c4bc6cd560 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 14 Apr 2014 12:29:39 +0100 Subject: [PATCH 10/16] use correct Trac ticket number --- src/sage/schemes/generic/spec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index 3ae5c475090..2ed8dec6870 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -189,7 +189,7 @@ def _apply_functor_to_morphism(self, f): # Compatibility with older versions of this module from sage.misc.superseded import deprecated_function_alias -is_Spec = deprecated_function_alias(7946, is_AffineScheme) +is_Spec = deprecated_function_alias(16158, is_AffineScheme) from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.schemes.generic.spec', 'Spec', AffineScheme) From cb82f0114374ea03d8c970d8bbd0972f0f5637f8 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 15 Apr 2014 10:27:12 +0100 Subject: [PATCH 11/16] fix raise syntax and a line of documentation --- src/sage/schemes/generic/scheme.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 83642a1be18..85ce17143e8 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -858,13 +858,13 @@ def __init__(self, R, S=None, category=None): """ from sage.categories.commutative_rings import CommutativeRings if not R in CommutativeRings(): - raise TypeError, "R (=%s) must be a commutative ring"%R + raise TypeError("R (=%s) must be a commutative ring" % R) self.__R = R if not S is None: if not S in CommutativeRings(): - raise TypeError, "S (=%s) must be a commutative ring"%S + raise TypeError("S (=%s) must be a commutative ring" % S) if not R.has_coerce_map_from(S): - raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) + raise ValueError("There must be a natural map S --> R, but S = %s and R = %s" % (S, R)) Scheme.__init__(self, S, category=category) def __setstate__(self, state): @@ -974,7 +974,7 @@ def _latex_(self): def __call__(self, *args): """ - Call syntax for Spec. + Construct a scheme-valued or topological point of ``self``. INPUT/OUTPUT: From dc0cacbb78955e11376ec52885516d63dc6cb675 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 10 May 2014 01:34:30 +0100 Subject: [PATCH 12/16] Trac 16158: add doctest to AffineScheme.__setstate__() --- src/sage/schemes/generic/scheme.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 85ce17143e8..a8a05ff1d43 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -873,6 +873,12 @@ def __setstate__(self, state): The name-mangled attribute ``__R`` used to be in a class called ``Spec``; we have to translate this mangled name. + + TESTS:: + + sage: S = Spec(QQ) + sage: loads(dumps(S)) + Spectrum of Rational Field """ if '_Spec__R' in state: state['_AffineScheme__R'] = state.pop('_Spec__R') From 8a65895c465ef8adb71bfad1048bc3d30f207994 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sun, 25 May 2014 19:45:30 +0100 Subject: [PATCH 13/16] Trac 16158: fix capitalisation in "Category of schemes" --- src/sage/schemes/generic/scheme.py | 2 +- src/sage/schemes/generic/spec.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index a8a05ff1d43..c43169c7b6f 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -852,7 +852,7 @@ def __init__(self, R, S=None, category=None): sage: S Spectrum of Integer Ring sage: S.category() - Category of Schemes + Category of schemes sage: type(S) """ diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index 2ed8dec6870..c23f1889048 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -93,7 +93,7 @@ def __init__(self, base_ring=None): sage: from sage.schemes.generic.spec import SpecFunctor sage: SpecFunctor() - Spec functor from Category of commutative rings to Category of Schemes + Spec functor from Category of commutative rings to Category of schemes sage: SpecFunctor(QQ) Spec functor from Category of commutative rings to Category of schemes over Rational Field From 2d4dbfba46d6ab0859006185ddb14fa07dbc7a02 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 17 Jul 2014 18:34:05 -0700 Subject: [PATCH 14/16] Some minor review tweaks. --- src/sage/schemes/generic/homset.py | 3 +-- src/sage/schemes/generic/scheme.py | 40 +++++++++++++++--------------- src/sage/schemes/generic/spec.py | 33 +++++++++++------------- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 1b8871de3ef..90f41f6af9d 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -204,11 +204,10 @@ def create_object(self, version, key, **extra_args): To: Affine Space of dimension 2 over Rational Field """ category = key[2] - as_point_homset = key[3] if len(key) >= 4 else False X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') - if as_point_homset: + if len(key) >= 4 and key[3]: return Y._point_homset(X, Y, category=category, base=base_ring, **extra_args) try: return X._homset(X, Y, category=category, base=base_ring, **extra_args) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index c43169c7b6f..7104a23a177 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -858,13 +858,13 @@ def __init__(self, R, S=None, category=None): """ from sage.categories.commutative_rings import CommutativeRings if not R in CommutativeRings(): - raise TypeError("R (=%s) must be a commutative ring" % R) + raise TypeError("R (={}) must be a commutative ring".format(R)) self.__R = R if not S is None: if not S in CommutativeRings(): - raise TypeError("S (=%s) must be a commutative ring" % S) + raise TypeError("S (={}) must be a commutative ring".format(S)) if not R.has_coerce_map_from(S): - raise ValueError("There must be a natural map S --> R, but S = %s and R = %s" % (S, R)) + raise ValueError("There must be a natural map S --> R, but S = {} and R = {}".format(S, R)) Scheme.__init__(self, S, category=category) def __setstate__(self, state): @@ -893,7 +893,7 @@ def _cmp_(self, X): INPUT: - - ``X`` -- anything. + - ``X`` -- anything OUTPUT: @@ -958,10 +958,10 @@ def _repr_(self): sage: Spec(PolynomialRing(QQ, 3, 'x'))._repr_() 'Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field' """ - return "Spectrum of %s"%self.__R + return "Spectrum of {}".format(self.__R) def _latex_(self): - """ + r""" Return a LaTeX representation of ``self``. OUTPUT: @@ -976,7 +976,7 @@ def _latex_(self): sage: S._latex_() '\\mathrm{Spec}(\\Bold{Z}[x_{0}, x_{1}])' """ - return "\\mathrm{Spec}(%s)" % self.__R._latex_() + return "\\mathrm{{Spec}}({})".format(self.__R._latex_()) def __call__(self, *args): """ @@ -987,10 +987,10 @@ def __call__(self, *args): The argument ``x`` must be one of the following: - a prime ideal of the coordinate ring; the output will - be the corresponding point of X + be the corresponding point of `X` - - a ring or a scheme S; the output will be the set X(S) of - S-valued points on X + - a ring or a scheme `S`; the output will be the set `X(S)` of + `S`-valued points on `X` EXAMPLES:: @@ -1010,6 +1010,7 @@ def __call__(self, *args): of Multivariate Polynomial Ring in x, y, z over Rational Field This indicates the fix of :trac:`12734`:: + sage: S = Spec(ZZ) sage: S(ZZ) Set of rational points of Spectrum of Integer Ring @@ -1074,7 +1075,7 @@ def is_noetherian(self): OUTPUT: - Boolean. Return True if this scheme is Noetherian. + Boolean. Return ``True`` if this scheme is Noetherian. EXAMPLES:: @@ -1125,7 +1126,7 @@ def base_extend(self, R): INPUT: - - ``R`` -- an affine scheme or a commutative ring. + - ``R`` -- an affine scheme or a commutative ring EXAMPLES:: @@ -1138,7 +1139,7 @@ def base_extend(self, R): if R in CommutativeRings(): return AffineScheme(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): - raise ValueError('The new base scheme must be a scheme over the old base scheme.') + raise ValueError('the new base scheme must be a scheme over the old base scheme') return AffineScheme(self.coordinate_ring().base_extend(new_base.coordinate_ring()), self.base_ring()) @@ -1163,13 +1164,13 @@ def hom(self, x, Y=None): INPUT: - ``x`` -- anything hat determines a scheme morphism. If ``x`` - is a scheme, try to determine a natural map to ``x``. + is a scheme, try to determine a natural map to ``x`` - - ``Y`` -- the codomain scheme (optional). If ``Y`` is not - given, try to determine ``Y`` from context. + - ``Y`` -- the codomain scheme (optional); if ``Y`` is not + given, try to determine ``Y`` from context - - ``check`` -- boolean (optional, default=``True``). Whether - to check the defining data for consistency. + - ``check`` -- boolean (optional, default: ``True``); whether + to check the defining data for consistency OUTPUT: @@ -1192,7 +1193,7 @@ def hom(self, x, Y=None): TESTS: - We can construct a morphism to an affine curve (trac #7956):: + We can construct a morphism to an affine curve (:trac:`7956`):: sage: S. = QQ[] sage: A1. = AffineSpace(QQ,1) @@ -1203,7 +1204,6 @@ def hom(self, x, Y=None): To: Affine Curve over Rational Field defined by p - 2 Defn: Defined on coordinates by sending (r) to (2, r) - """ if is_Scheme(x): return self.Hom(x).natural_map() diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index c23f1889048..df425020957 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -6,7 +6,6 @@ - William Stein (2006): initial implementation - Peter Bruin (2014): rewrite Spec as a functor - """ #******************************************************************************* @@ -32,7 +31,7 @@ def Spec(R, S=None): OUTPUT: - - ``AffineScheme`` -- the affine scheme `\text{Spec}(R)` + - ``AffineScheme`` -- the affine scheme `\mathrm{Spec}(R)` EXAMPLES:: @@ -95,8 +94,8 @@ def __init__(self, base_ring=None): sage: SpecFunctor() Spec functor from Category of commutative rings to Category of schemes sage: SpecFunctor(QQ) - Spec functor from Category of commutative rings to Category of schemes over Rational Field - + Spec functor from Category of commutative rings to + Category of schemes over Rational Field """ from sage.categories.all import CommutativeAlgebras, CommutativeRings, Schemes @@ -111,7 +110,7 @@ def __init__(self, base_ring=None): domain = CommutativeRings() codomain = Schemes(AffineScheme(base_ring)) else: - raise TypeError('base (= %s) must be a commutative ring') + raise TypeError('base (= {}) must be a commutative ring'.format(base_ring)) self._base_ring = base_ring super(SpecFunctor, self).__init__(domain, codomain) @@ -119,40 +118,38 @@ def _repr_(self): """ Return a string representation of ``self``. - EXAMPLE:: + EXAMPLES:: sage: from sage.schemes.generic.spec import SpecFunctor sage: SpecFunctor(QQ) - Spec functor from Category of commutative rings to Category of schemes over Rational Field - + Spec functor from Category of commutative rings to + Category of schemes over Rational Field """ - return 'Spec functor from %s to %s' % (self.domain(), self.codomain()) + return 'Spec functor from {} to {}'.format(self.domain(), self.codomain()) def _latex_(self): r""" Return a LaTeX representation of ``self``. - EXAMPLE:: + EXAMPLES:: sage: from sage.schemes.generic.spec import SpecFunctor sage: latex(SpecFunctor()) \mathrm{Spec}\colon \mathbf{CommutativeRings} \longrightarrow \mathbf{Schemes} - """ - return (r'\mathrm{Spec}\colon %s \longrightarrow %s' - % (self.domain()._latex_(), self.codomain()._latex_())) + return r'\mathrm{{Spec}}\colon {} \longrightarrow {}'.format( + self.domain()._latex_(), self.codomain()._latex_()) def _apply_functor(self, A): """ Apply the Spec functor to the commutative ring ``A``. - EXAMPLE:: + EXAMPLES:: sage: from sage.schemes.generic.spec import SpecFunctor sage: F = SpecFunctor() - sage: F(RR) + sage: F(RR) # indirect doctest Spectrum of Real Field with 53 bits of precision - """ return AffineScheme(A, self._base_ring) @@ -160,7 +157,7 @@ def _apply_functor_to_morphism(self, f): """ Apply the Spec functor to the ring homomorphism ``f``. - EXAMPLE:: + EXAMPLES:: sage: from sage.schemes.generic.spec import SpecFunctor sage: F = SpecFunctor(GF(7)) @@ -176,7 +173,6 @@ def _apply_functor_to_morphism(self, f): To: Univariate Polynomial Ring in t over Finite Field of size 7 Defn: x |--> t^2 y |--> t^3 - """ A = f.domain() B = f.codomain() @@ -193,3 +189,4 @@ def _apply_functor_to_morphism(self, f): from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.schemes.generic.spec', 'Spec', AffineScheme) + From f86c030c8e9f85dca352af3a25b636ea8b0b234e Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 17 Jul 2014 18:39:12 -0700 Subject: [PATCH 15/16] Added one other # indirect doctest. --- src/sage/schemes/generic/spec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index df425020957..51c5f928cc3 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -164,7 +164,7 @@ def _apply_functor_to_morphism(self, f): sage: A. = GF(7)[] sage: B. = GF(7)[] sage: f = A.hom((t^2, t^3)) - sage: Spec(f) + sage: Spec(f) # indirect doctest Affine Scheme morphism: From: Spectrum of Univariate Polynomial Ring in t over Finite Field of size 7 To: Spectrum of Multivariate Polynomial Ring in x, y over Finite Field of size 7 From 185b49cd73907d2214401f96058e61b0eb334d8e Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Fri, 18 Jul 2014 11:28:31 +0100 Subject: [PATCH 16/16] Trac 16158: minor formatting changes --- src/sage/schemes/generic/homset.py | 2 +- src/sage/schemes/generic/scheme.py | 37 +++++++++++++----------------- src/sage/schemes/generic/spec.py | 1 - 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 90f41f6af9d..86547dd06db 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -207,7 +207,7 @@ def create_object(self, version, key, **extra_args): X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') - if len(key) >= 4 and key[3]: + if len(key) >= 4 and key[3]: # as_point_homset=True return Y._point_homset(X, Y, category=category, base=base_ring, **extra_args) try: return X._homset(X, Y, category=category, base=base_ring, **extra_args) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 7104a23a177..d2f399fe82b 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -340,10 +340,10 @@ def point(self, v, check=True): INPUT: - - ``v`` -- anything that defines a point. + - ``v`` -- anything that defines a point - - ``check`` -- boolean (optional, default=``True``). Whether - to check the defining data for consistency. + - ``check`` -- boolean (optional, default: ``True``); whether + to check the defining data for consistency OUTPUT: @@ -613,14 +613,14 @@ def hom(self, x, Y=None, check=True): INPUT: - - ``x`` -- anything hat determines a scheme morphism. If ``x`` - is a scheme, try to determine a natural map to ``x``. + - ``x`` -- anything that determines a scheme morphism; if + ``x`` is a scheme, try to determine a natural map to ``x`` - - ``Y`` -- the codomain scheme (optional). If ``Y`` is not - given, try to determine ``Y`` from context. + - ``Y`` -- the codomain scheme (optional); if ``Y`` is not + given, try to determine ``Y`` from context - - ``check`` -- boolean (optional, default=``True``). Whether - to check the defining data for consistency. + - ``check`` -- boolean (optional, default: ``True``); whether + to check the defining data for consistency OUTPUT: @@ -648,12 +648,12 @@ def _Hom_(self, Y, category=None, check=True): INPUT: - - ``Y`` -- a scheme. The codomain of the Hom-set. + - ``Y`` -- a scheme; the codomain of the Hom-set - - ``category`` -- a category (optional). The category of the - Hom-set. + - ``category`` -- a category (optional); the category of the + Hom-set - - ``check`` -- boolean (optional, default=``True``). Whether + - ``check`` -- boolean (optional, default: ``True``); whether to check the defining data for consistency. OUTPUT: @@ -1071,11 +1071,7 @@ def coordinate_ring(self): def is_noetherian(self): """ - Test whether ``self`` is Noetherian. - - OUTPUT: - - Boolean. Return ``True`` if this scheme is Noetherian. + Return ``True`` if ``self`` is Noetherian, ``False`` otherwise. EXAMPLES:: @@ -1163,8 +1159,8 @@ def hom(self, x, Y=None): INPUT: - - ``x`` -- anything hat determines a scheme morphism. If ``x`` - is a scheme, try to determine a natural map to ``x`` + - ``x`` -- anything that determines a scheme morphism; if + ``x`` is a scheme, try to determine a natural map to ``x`` - ``Y`` -- the codomain scheme (optional); if ``Y`` is not given, try to determine ``Y`` from context @@ -1210,4 +1206,3 @@ def hom(self, x, Y=None): if Y is None and is_RingHomomorphism(x): Y = AffineScheme(x.domain()) return Scheme.hom(self, x, Y) - diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index 51c5f928cc3..2f7ddb4440c 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -189,4 +189,3 @@ def _apply_functor_to_morphism(self, f): from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.schemes.generic.spec', 'Spec', AffineScheme) -