Commutative rings

class sage.categories.commutative_rings.CommutativeRings(base_category)[source]

Bases: CategoryWithAxiom_singleton

The category of commutative rings.

commutative rings with unity, i.e. rings with commutative * and a multiplicative identity

EXAMPLES:

sage: C = CommutativeRings(); C
Category of commutative rings
sage: C.super_categories()
[Category of rings, Category of commutative monoids]
>>> from sage.all import *
>>> C = CommutativeRings(); C
Category of commutative rings
>>> C.super_categories()
[Category of rings, Category of commutative monoids]
class CartesianProducts(category, *args)[source]

Bases: CartesianProductsCategory

extra_super_categories()[source]

Let Sage knows that Cartesian products of commutative rings is a commutative ring.

EXAMPLES:

sage: CommutativeRings().Commutative().CartesianProducts().extra_super_categories()
[Category of commutative rings]
sage: cartesian_product([ZZ, Zmod(34),
....:                    QQ, GF(5)]) in CommutativeRings()
True
>>> from sage.all import *
>>> CommutativeRings().Commutative().CartesianProducts().extra_super_categories()
[Category of commutative rings]
>>> cartesian_product([ZZ, Zmod(Integer(34)),
...                    QQ, GF(Integer(5))]) in CommutativeRings()
True
class ElementMethods[source]

Bases: object

class Finite(base_category)[source]

Bases: CategoryWithAxiom_singleton

Check that Sage knows that Cartesian products of finite commutative rings is a finite commutative ring.

EXAMPLES:

sage: cartesian_product([Zmod(34),
....:                    GF(5)]) in Rings().Commutative().Finite()
True
>>> from sage.all import *
>>> cartesian_product([Zmod(Integer(34)),
...                    GF(Integer(5))]) in Rings().Commutative().Finite()
True
class ParentMethods[source]

Bases: object

cyclotomic_cosets(q, cosets=None)[source]

Return the (multiplicative) orbits of q in the ring.

Let \(R\) be a finite commutative ring. The group of invertible elements \(R^*\) in \(R\) gives rise to a group action on \(R\) by multiplication. An orbit of the subgroup generated by an invertible element \(q\) is called a \(q\)-cyclotomic coset (since in a finite ring, each invertible element is a root of unity).

These cosets arise in the theory of minimal polynomials of finite fields, duadic codes and combinatorial designs. Fix a primitive element \(z\) of \(GF(q^k)\). The minimal polynomial of \(z^s\) over \(GF(q)\) is given by

\[M_s(x) = \prod_{i \in C_s} (x - z^i),\]

where \(C_s\) is the \(q\)-cyclotomic coset mod \(n\) containing \(s\), \(n = q^k - 1\).

Note

When \(R = \ZZ / n \ZZ\) the smallest element of each coset is sometimes called a coset leader. This function returns sorted lists so that the coset leader will always be the first element of the coset.

INPUT:

  • q – an invertible element of the ring

  • cosets – an optional lists of elements of self. If provided, the function only return the list of cosets that contain some element from cosets.

OUTPUT: list of lists

EXAMPLES:

sage: Zmod(11).cyclotomic_cosets(2)
[[0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
sage: Zmod(15).cyclotomic_cosets(2)
[[0], [1, 2, 4, 8], [3, 6, 9, 12], [5, 10], [7, 11, 13, 14]]
>>> from sage.all import *
>>> Zmod(Integer(11)).cyclotomic_cosets(Integer(2))
[[0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
>>> Zmod(Integer(15)).cyclotomic_cosets(Integer(2))
[[0], [1, 2, 4, 8], [3, 6, 9, 12], [5, 10], [7, 11, 13, 14]]

Since the group of invertible elements of a finite field is cyclic, the set of squares is a particular case of cyclotomic coset:

sage: # needs sage.rings.finite_rings
sage: K = GF(25, 'z')
sage: a = K.multiplicative_generator()
sage: K.cyclotomic_cosets(a**2, cosets=[1])
[[1, 2, 3, 4, z + 1, z + 3,
  2*z + 1, 2*z + 2, 3*z + 3,
  3*z + 4, 4*z + 2, 4*z + 4]]
sage: sorted(b for b in K if not b.is_zero() and b.is_square())
[1, 2, 3, 4, z + 1, z + 3,
 2*z + 1, 2*z + 2, 3*z + 3,
 3*z + 4, 4*z + 2, 4*z + 4]
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> K = GF(Integer(25), 'z')
>>> a = K.multiplicative_generator()
>>> K.cyclotomic_cosets(a**Integer(2), cosets=[Integer(1)])
[[1, 2, 3, 4, z + 1, z + 3,
  2*z + 1, 2*z + 2, 3*z + 3,
  3*z + 4, 4*z + 2, 4*z + 4]]
>>> sorted(b for b in K if not b.is_zero() and b.is_square())
[1, 2, 3, 4, z + 1, z + 3,
 2*z + 1, 2*z + 2, 3*z + 3,
 3*z + 4, 4*z + 2, 4*z + 4]

We compute some examples of minimal polynomials:

sage: # needs sage.rings.finite_rings
sage: K = GF(27, 'z')
sage: a = K.multiplicative_generator()
sage: R.<X> = PolynomialRing(K, 'X')
sage: a.minimal_polynomial('X')
X^3 + 2*X + 1

sage: cyc3 = Zmod(26).cyclotomic_cosets(3, cosets=[1]); cyc3
[[1, 3, 9]]
sage: prod(X - a**i for i in cyc3[0])                               # needs sage.rings.finite_rings
X^3 + 2*X + 1
sage: (a**7).minimal_polynomial('X')                                # needs sage.rings.finite_rings
X^3 + X^2 + 2*X + 1
sage: cyc7 = Zmod(26).cyclotomic_cosets(3, cosets=[7]); cyc7
[[7, 11, 21]]
sage: prod(X - a**i for i in cyc7[0])                               # needs sage.rings.finite_rings
X^3 + X^2 + 2*X + 1
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> K = GF(Integer(27), 'z')
>>> a = K.multiplicative_generator()
>>> R = PolynomialRing(K, 'X', names=('X',)); (X,) = R._first_ngens(1)
>>> a.minimal_polynomial('X')
X^3 + 2*X + 1

>>> cyc3 = Zmod(Integer(26)).cyclotomic_cosets(Integer(3), cosets=[Integer(1)]); cyc3
[[1, 3, 9]]
>>> prod(X - a**i for i in cyc3[Integer(0)])                               # needs sage.rings.finite_rings
X^3 + 2*X + 1
>>> (a**Integer(7)).minimal_polynomial('X')                                # needs sage.rings.finite_rings
X^3 + X^2 + 2*X + 1
>>> cyc7 = Zmod(Integer(26)).cyclotomic_cosets(Integer(3), cosets=[Integer(7)]); cyc7
[[7, 11, 21]]
>>> prod(X - a**i for i in cyc7[Integer(0)])                               # needs sage.rings.finite_rings
X^3 + X^2 + 2*X + 1

Cyclotomic cosets of fields are useful in combinatorial design theory to provide so called difference families (see Wikipedia article Difference_set and difference_family). This is illustrated on the following examples:

sage: K = GF(5)
sage: a = K.multiplicative_generator()                              # needs sage.libs.pari
sage: H = K.cyclotomic_cosets(a**2, cosets=[1, 2]); H               # needs sage.rings.finite_rings
[[1, 4], [2, 3]]
sage: sorted(x - y for D in H for x in D for y in D if x != y)      # needs sage.rings.finite_rings
[1, 2, 3, 4]

sage: K = GF(37)
sage: a = K.multiplicative_generator()                              # needs sage.libs.pari
sage: H = K.cyclotomic_cosets(a**4, cosets=[1]); H                  # needs sage.rings.finite_rings
[[1, 7, 9, 10, 12, 16, 26, 33, 34]]
sage: sorted(x - y for D in H for x in D for y in D if x != y)      # needs sage.rings.finite_rings
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., 33, 34, 34, 35, 35, 36, 36]
>>> from sage.all import *
>>> K = GF(Integer(5))
>>> a = K.multiplicative_generator()                              # needs sage.libs.pari
>>> H = K.cyclotomic_cosets(a**Integer(2), cosets=[Integer(1), Integer(2)]); H               # needs sage.rings.finite_rings
[[1, 4], [2, 3]]
>>> sorted(x - y for D in H for x in D for y in D if x != y)      # needs sage.rings.finite_rings
[1, 2, 3, 4]

>>> K = GF(Integer(37))
>>> a = K.multiplicative_generator()                              # needs sage.libs.pari
>>> H = K.cyclotomic_cosets(a**Integer(4), cosets=[Integer(1)]); H                  # needs sage.rings.finite_rings
[[1, 7, 9, 10, 12, 16, 26, 33, 34]]
>>> sorted(x - y for D in H for x in D for y in D if x != y)      # needs sage.rings.finite_rings
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., 33, 34, 34, 35, 35, 36, 36]

The method cyclotomic_cosets works on any finite commutative ring:

sage: R = cartesian_product([GF(7), Zmod(14)])
sage: a = R((3,5))
sage: R.cyclotomic_cosets((3,5), [(1,1)])
[[(1, 1), (2, 11), (3, 5), (4, 9), (5, 3), (6, 13)]]
>>> from sage.all import *
>>> R = cartesian_product([GF(Integer(7)), Zmod(Integer(14))])
>>> a = R((Integer(3),Integer(5)))
>>> R.cyclotomic_cosets((Integer(3),Integer(5)), [(Integer(1),Integer(1))])
[[(1, 1), (2, 11), (3, 5), (4, 9), (5, 3), (6, 13)]]
extra_super_categories()[source]

Let Sage know that finite commutative rings are Noetherian.

EXAMPLES:

sage: CommutativeRings().Finite().extra_super_categories()
[Category of noetherian rings]
>>> from sage.all import *
>>> CommutativeRings().Finite().extra_super_categories()
[Category of noetherian rings]
class ParentMethods[source]

Bases: object

derivation(arg=None, twist=None)[source]

Return the twisted or untwisted derivation over this ring specified by arg.

Note

A twisted derivation with respect to \(\theta\) (or a \(\theta\)-derivation for short) is an additive map \(d\) satisfying the following axiom for all \(x, y\) in the domain:

\[d(xy) = \theta(x) d(y) + d(x) y.\]

INPUT:

  • arg – (optional) a generator or a list of coefficients that defines the derivation

  • twist – (optional) the twisting homomorphism

EXAMPLES:

sage: R.<x,y,z> = QQ[]
sage: R.derivation()                                                        # needs sage.modules
d/dx
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> R.derivation()                                                        # needs sage.modules
d/dx

In that case, arg could be a generator:

sage: R.derivation(y)                                                       # needs sage.modules
d/dy
>>> from sage.all import *
>>> R.derivation(y)                                                       # needs sage.modules
d/dy

or a list of coefficients:

sage: R.derivation([1,2,3])                                                 # needs sage.modules
d/dx + 2*d/dy + 3*d/dz
>>> from sage.all import *
>>> R.derivation([Integer(1),Integer(2),Integer(3)])                                                 # needs sage.modules
d/dx + 2*d/dy + 3*d/dz

It is not possible to define derivations with respect to a polynomial which is not a variable:

sage: R.derivation(x^2)                                                     # needs sage.modules
Traceback (most recent call last):
...
ValueError: unable to create the derivation
>>> from sage.all import *
>>> R.derivation(x**Integer(2))                                                     # needs sage.modules
Traceback (most recent call last):
...
ValueError: unable to create the derivation

Here is an example with twisted derivations:

sage: R.<x,y,z> = QQ[]
sage: theta = R.hom([x^2, y^2, z^2])
sage: f = R.derivation(twist=theta); f                                      # needs sage.modules
0
sage: f.parent()                                                            # needs sage.modules
Module of twisted derivations over Multivariate Polynomial Ring in x, y, z
 over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> theta = R.hom([x**Integer(2), y**Integer(2), z**Integer(2)])
>>> f = R.derivation(twist=theta); f                                      # needs sage.modules
0
>>> f.parent()                                                            # needs sage.modules
Module of twisted derivations over Multivariate Polynomial Ring in x, y, z
 over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)

Specifying a scalar, the returned twisted derivation is the corresponding multiple of \(\theta - id\):

sage: R.derivation(1, twist=theta)                                          # needs sage.modules
[x |--> x^2, y |--> y^2, z |--> z^2] - id
sage: R.derivation(x, twist=theta)                                          # needs sage.modules
x*([x |--> x^2, y |--> y^2, z |--> z^2] - id)
>>> from sage.all import *
>>> R.derivation(Integer(1), twist=theta)                                          # needs sage.modules
[x |--> x^2, y |--> y^2, z |--> z^2] - id
>>> R.derivation(x, twist=theta)                                          # needs sage.modules
x*([x |--> x^2, y |--> y^2, z |--> z^2] - id)
derivation_module(codomain=None, twist=None)[source]

Return the module of derivations over this ring.

INPUT:

  • codomain – an algebra over this ring or a ring homomorphism whose domain is this ring or None (default: None); if it is a morphism, the codomain of derivations will be the codomain of the morphism viewed as an algebra over self through the given morphism; if None, the codomain will be this ring

  • twist – a morphism from this ring to codomain or None (default: None); if None, the coercion map from this ring to codomain will be used

Note

A twisted derivation with respect to \(\theta\) (or a \(\theta\)-derivation for short) is an additive map \(d\) satisfying the following axiom for all \(x, y\) in the domain:

\[d(xy) = \theta(x) d(y) + d(x) y.\]

EXAMPLES:

sage: R.<x,y,z> = QQ[]
sage: M = R.derivation_module(); M                                          # needs sage.modules
Module of derivations over
 Multivariate Polynomial Ring in x, y, z over Rational Field
sage: M.gens()                                                              # needs sage.modules
(d/dx, d/dy, d/dz)
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> M = R.derivation_module(); M                                          # needs sage.modules
Module of derivations over
 Multivariate Polynomial Ring in x, y, z over Rational Field
>>> M.gens()                                                              # needs sage.modules
(d/dx, d/dy, d/dz)

We can specify a different codomain:

sage: K = R.fraction_field()
sage: M = R.derivation_module(K); M                                         # needs sage.modules
Module of derivations
 from Multivariate Polynomial Ring in x, y, z over Rational Field
   to Fraction Field of
      Multivariate Polynomial Ring in x, y, z over Rational Field
sage: M.gen() / x                                                           # needs sage.modules
1/x*d/dx
>>> from sage.all import *
>>> K = R.fraction_field()
>>> M = R.derivation_module(K); M                                         # needs sage.modules
Module of derivations
 from Multivariate Polynomial Ring in x, y, z over Rational Field
   to Fraction Field of
      Multivariate Polynomial Ring in x, y, z over Rational Field
>>> M.gen() / x                                                           # needs sage.modules
1/x*d/dx

Here is an example with a non-canonical defining morphism:

sage: ev = R.hom([QQ(0), QQ(1), QQ(2)])
sage: ev
Ring morphism:
  From: Multivariate Polynomial Ring in x, y, z over Rational Field
  To:   Rational Field
  Defn: x |--> 0
        y |--> 1
        z |--> 2
sage: M = R.derivation_module(ev)                                           # needs sage.modules
sage: M                                                                     # needs sage.modules
Module of derivations
 from Multivariate Polynomial Ring in x, y, z over Rational Field
   to Rational Field
>>> from sage.all import *
>>> ev = R.hom([QQ(Integer(0)), QQ(Integer(1)), QQ(Integer(2))])
>>> ev
Ring morphism:
  From: Multivariate Polynomial Ring in x, y, z over Rational Field
  To:   Rational Field
  Defn: x |--> 0
        y |--> 1
        z |--> 2
>>> M = R.derivation_module(ev)                                           # needs sage.modules
>>> M                                                                     # needs sage.modules
Module of derivations
 from Multivariate Polynomial Ring in x, y, z over Rational Field
   to Rational Field

Elements in \(M\) acts as derivations at \((0,1,2)\):

sage: # needs sage.modules
sage: Dx = M.gen(0); Dx
d/dx
sage: Dy = M.gen(1); Dy
d/dy
sage: Dz = M.gen(2); Dz
d/dz
sage: f = x^2 + y^2 + z^2
sage: Dx(f)  # = 2*x evaluated at (0,1,2)
0
sage: Dy(f)  # = 2*y evaluated at (0,1,2)
2
sage: Dz(f)  # = 2*z evaluated at (0,1,2)
4
>>> from sage.all import *
>>> # needs sage.modules
>>> Dx = M.gen(Integer(0)); Dx
d/dx
>>> Dy = M.gen(Integer(1)); Dy
d/dy
>>> Dz = M.gen(Integer(2)); Dz
d/dz
>>> f = x**Integer(2) + y**Integer(2) + z**Integer(2)
>>> Dx(f)  # = 2*x evaluated at (0,1,2)
0
>>> Dy(f)  # = 2*y evaluated at (0,1,2)
2
>>> Dz(f)  # = 2*z evaluated at (0,1,2)
4

An example with a twisting homomorphism:

sage: theta = R.hom([x^2, y^2, z^2])
sage: M = R.derivation_module(twist=theta); M                               # needs sage.modules
Module of twisted derivations over Multivariate Polynomial Ring in x, y, z
 over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
>>> from sage.all import *
>>> theta = R.hom([x**Integer(2), y**Integer(2), z**Integer(2)])
>>> M = R.derivation_module(twist=theta); M                               # needs sage.modules
Module of twisted derivations over Multivariate Polynomial Ring in x, y, z
 over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)

See also

derivation()

frobenius_endomorphism(n=1)[source]

Return the Frobenius endomorphism.

INPUT:

  • n – nonnegative integer (default: 1)

OUTPUT:

The \(n\)-th power of the absolute arithmetic Frobenius endomorphism on this commutative ring.

EXAMPLES:

sage: K.<u> = PowerSeriesRing(GF(5))
sage: Frob = K.frobenius_endomorphism(); Frob
Frobenius endomorphism x |--> x^5 of Power Series Ring in u
 over Finite Field of size 5
sage: Frob(u)
u^5
>>> from sage.all import *
>>> K = PowerSeriesRing(GF(Integer(5)), names=('u',)); (u,) = K._first_ngens(1)
>>> Frob = K.frobenius_endomorphism(); Frob
Frobenius endomorphism x |--> x^5 of Power Series Ring in u
 over Finite Field of size 5
>>> Frob(u)
u^5

We can specify a power:

sage: f = K.frobenius_endomorphism(2); f
Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u
 over Finite Field of size 5
sage: f(1+u)
1 + u^25
>>> from sage.all import *
>>> f = K.frobenius_endomorphism(Integer(2)); f
Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u
 over Finite Field of size 5
>>> f(Integer(1)+u)
1 + u^25
is_commutative()[source]

Return whether the ring is commutative.

The answer is True only if the category is a sub-category of CommutativeRings.

It is recommended to use instead R in Rings().Commutative().

EXAMPLES:

sage: QQ.is_commutative()
True
sage: QQ['x,y,z'].is_commutative()
True
>>> from sage.all import *
>>> QQ.is_commutative()
True
>>> QQ['x,y,z'].is_commutative()
True
krull_dimension()[source]

Return the Krull dimension of this commutative ring.

The Krull dimension is the length of the longest ascending chain of prime ideals.

This raises NotImplementedError by default for generic commutative rings.

Fields and PIDs, with Krull dimension equal to 0 and 1, respectively, have naive implementations of krull_dimension. Orders in number fields also have Krull dimension 1.

EXAMPLES:

Some polynomial rings:

sage: T.<x,y> = PolynomialRing(QQ,2); T
Multivariate Polynomial Ring in x, y over Rational Field
sage: T.krull_dimension()
2
sage: U.<x,y,z> = PolynomialRing(ZZ,3); U
Multivariate Polynomial Ring in x, y, z over Integer Ring
sage: U.krull_dimension()
4
>>> from sage.all import *
>>> T = PolynomialRing(QQ,Integer(2), names=('x', 'y',)); (x, y,) = T._first_ngens(2); T
Multivariate Polynomial Ring in x, y over Rational Field
>>> T.krull_dimension()
2
>>> U = PolynomialRing(ZZ,Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = U._first_ngens(3); U
Multivariate Polynomial Ring in x, y, z over Integer Ring
>>> U.krull_dimension()
4

All orders in number fields have Krull dimension 1, including non-maximal orders:

sage: # needs sage.rings.number_field
sage: K.<i> = QuadraticField(-1)
sage: R = K.order(2*i); R
Order of conductor 2 generated by 2*i
 in Number Field in i with defining polynomial x^2 + 1 with i = 1*I
sage: R.is_maximal()
False
sage: R.krull_dimension()
1
sage: R = K.maximal_order(); R
Gaussian Integers generated by i in Number Field in i
 with defining polynomial x^2 + 1 with i = 1*I
sage: R.krull_dimension()
1
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> R = K.order(Integer(2)*i); R
Order of conductor 2 generated by 2*i
 in Number Field in i with defining polynomial x^2 + 1 with i = 1*I
>>> R.is_maximal()
False
>>> R.krull_dimension()
1
>>> R = K.maximal_order(); R
Gaussian Integers generated by i in Number Field in i
 with defining polynomial x^2 + 1 with i = 1*I
>>> R.krull_dimension()
1
over(base=None, gen=None, gens=None, name=None, names=None)[source]

Return this ring, considered as an extension of base.

INPUT:

  • base – a commutative ring or a morphism or None (default: None); the base of this extension or its defining morphism

  • gen – a generator of this extension (over its base) or None (default: None)

  • gens – list of generators of this extension (over its base) or None (default: None)

  • name – a variable name or None (default: None)

  • names – list or a tuple of variable names or None (default: None)

EXAMPLES:

We construct an extension of finite fields:

sage: # needs sage.rings.finite_rings
sage: F = GF(5^2)
sage: k = GF(5^4)
sage: z4 = k.gen()
sage: K = k.over(F); K                                                  # needs sage.modules
Field in z4 with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> F = GF(Integer(5)**Integer(2))
>>> k = GF(Integer(5)**Integer(4))
>>> z4 = k.gen()
>>> K = k.over(F); K                                                  # needs sage.modules
Field in z4 with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base

If not explicitly given, the default generator of the top ring (here k) is used and the same name is kept:

sage: K.gen()                                                           # needs sage.modules sage.rings.finite_rings
z4
sage: K(z4)                                                             # needs sage.modules sage.rings.finite_rings
z4
>>> from sage.all import *
>>> K.gen()                                                           # needs sage.modules sage.rings.finite_rings
z4
>>> K(z4)                                                             # needs sage.modules sage.rings.finite_rings
z4

However, it is possible to specify another generator and/or another name. For example:

sage: # needs sage.modules sage.rings.finite_rings
sage: Ka = k.over(F, name='a'); Ka
Field in a with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base
sage: Ka.gen()
a
sage: Ka(z4)
a

sage: # needs sage.modules sage.rings.finite_rings
sage: Kb = k.over(F, gen=-z4+1, name='b')
sage: Kb
Field in b with defining polynomial x^2 + z2*x + 4 over its base
sage: Kb.gen()
b
sage: Kb(-z4+1)
b
>>> from sage.all import *
>>> # needs sage.modules sage.rings.finite_rings
>>> Ka = k.over(F, name='a'); Ka
Field in a with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base
>>> Ka.gen()
a
>>> Ka(z4)
a

>>> # needs sage.modules sage.rings.finite_rings
>>> Kb = k.over(F, gen=-z4+Integer(1), name='b')
>>> Kb
Field in b with defining polynomial x^2 + z2*x + 4 over its base
>>> Kb.gen()
b
>>> Kb(-z4+Integer(1))
b

Note that the shortcut K.<a> is also available:

sage: KKa.<a> = k.over(F)                                               # needs sage.modules sage.rings.finite_rings
sage: KKa is Ka                                                         # needs sage.modules sage.rings.finite_rings
True
>>> from sage.all import *
>>> KKa = k.over(F, names=('a',)); (a,) = KKa._first_ngens(1)# needs sage.modules sage.rings.finite_rings
>>> KKa is Ka                                                         # needs sage.modules sage.rings.finite_rings
True

Building an extension on top of another extension is allowed:

sage: L = GF(5^12).over(K); L                                           # needs sage.modules sage.rings.finite_rings
Field in z12 with defining polynomial
 x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
sage: L.base_ring()                                                     # needs sage.modules sage.rings.finite_rings
Field in z4 with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base
>>> from sage.all import *
>>> L = GF(Integer(5)**Integer(12)).over(K); L                                           # needs sage.modules sage.rings.finite_rings
Field in z12 with defining polynomial
 x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
>>> L.base_ring()                                                     # needs sage.modules sage.rings.finite_rings
Field in z4 with defining polynomial
 x^2 + (4*z2 + 3)*x + z2 over its base

The successive bases of an extension are accessible via the method sage.rings.ring_extension.RingExtension_generic.bases():

sage: L.bases()                                                         # needs sage.modules sage.rings.finite_rings
[Field in z12 with defining polynomial
  x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base,
 Field in z4 with defining polynomial
  x^2 + (4*z2 + 3)*x + z2 over its base,
 Finite Field in z2 of size 5^2]
>>> from sage.all import *
>>> L.bases()                                                         # needs sage.modules sage.rings.finite_rings
[Field in z12 with defining polynomial
  x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base,
 Field in z4 with defining polynomial
  x^2 + (4*z2 + 3)*x + z2 over its base,
 Finite Field in z2 of size 5^2]

When base is omitted, the canonical base of the ring is used:

sage: S.<x> = QQ[]
sage: E = S.over(); E                                                   # needs sage.modules
Univariate Polynomial Ring in x over Rational Field over its base
sage: E.base_ring()                                                     # needs sage.modules
Rational Field
>>> from sage.all import *
>>> S = QQ['x']; (x,) = S._first_ngens(1)
>>> E = S.over(); E                                                   # needs sage.modules
Univariate Polynomial Ring in x over Rational Field over its base
>>> E.base_ring()                                                     # needs sage.modules
Rational Field

Here is an example where base is a defining morphism:

sage: # needs sage.modules sage.rings.number_field
sage: k.<a> = QQ.extension(x^2 - 2)
sage: l.<b> = QQ.extension(x^4 - 2)
sage: f = k.hom([b^2])
sage: L = l.over(f)
sage: L
Field in b with defining polynomial x^2 - a over its base
sage: L.base_ring()
Number Field in a with defining polynomial x^2 - 2
>>> from sage.all import *
>>> # needs sage.modules sage.rings.number_field
>>> k = QQ.extension(x**Integer(2) - Integer(2), names=('a',)); (a,) = k._first_ngens(1)
>>> l = QQ.extension(x**Integer(4) - Integer(2), names=('b',)); (b,) = l._first_ngens(1)
>>> f = k.hom([b**Integer(2)])
>>> L = l.over(f)
>>> L
Field in b with defining polynomial x^2 - a over its base
>>> L.base_ring()
Number Field in a with defining polynomial x^2 - 2

Similarly, one can create a tower of extensions:

sage: # needs sage.modules sage.rings.number_field
sage: K = k.over()
sage: L = l.over(Hom(K, l)(f)); L
Field in b with defining polynomial x^2 - a over its base
sage: L.base_ring()
Field in a with defining polynomial x^2 - 2 over its base
sage: L.bases()
[Field in b with defining polynomial x^2 - a over its base,
 Field in a with defining polynomial x^2 - 2 over its base,
 Rational Field]
>>> from sage.all import *
>>> # needs sage.modules sage.rings.number_field
>>> K = k.over()
>>> L = l.over(Hom(K, l)(f)); L
Field in b with defining polynomial x^2 - a over its base
>>> L.base_ring()
Field in a with defining polynomial x^2 - 2 over its base
>>> L.bases()
[Field in b with defining polynomial x^2 - a over its base,
 Field in a with defining polynomial x^2 - 2 over its base,
 Rational Field]