Extension of rings - General Rings, Ideals, and Morphisms

Skip to content
Back to top
View this page
Edit this page

# Extension of rings

Sage offers the possibility to work with ring extensions \(L/K\) as actual parents and perform meaningful operations on them and their elements.

The simplest way to build an extension is to use the method `sage.categories.commutative_rings.CommutativeRings.ParentMethods.over()` on the top ring, that is \(L\). For example, the following line constructs the extension of finite fields \(\mathbf{F}_{5^4}/\mathbf{F}_{5^2}\):

Sage

    sage: GF(5^4).over(GF(5^2))
    Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base

Python

    >>> from sage.all import *
    >>> GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))
    Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base

By default, Sage reuses the canonical generator of the top ring (here \(z_4 \in \mathbf{F}_{5^4}\)), together with its name. However, the user can customize them by passing in appropriate arguments:

Sage

    sage: F = GF(5^2)
    sage: k = GF(5^4)
    sage: z4 = k.gen()
    sage: K.<a> = k.over(F, gen=1-z4); K
    Field in a with defining polynomial x^2 + z2*x + 4 over its base

[Python]

    >>> from sage.all import *
    >>> F = GF(Integer(5)**Integer(2))
    >>> k = GF(Integer(5)**Integer(4))
    >>> z4 = k.gen()
    >>> K = k.over(F, gen=Integer(1)-z4, names=('a',)); (a,) = K._first_ngens(1); K
    Field in a with defining polynomial x^2 + z2*x + 4 over its base

The base of the extension is available via the method `base()` (or equivalently `base_ring()`):

Sage

    sage: K.base()
    Finite Field in z2 of size 5^2

Python

    >>> from sage.all import *
    >>> K.base()
    Finite Field in z2 of size 5^2

It is also possible to build an extension on top of another extension, obtaining this way a tower of extensions:

Sage

    sage: L.<b> = GF(5^8).over(K); L
    Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base
    sage: L.base()
    Field in a with defining polynomial x^2 + z2*x + 4 over its base
    sage: L.base().base()
    Finite Field in z2 of size 5^2

[Python]

    >>> from sage.all import *
    >>> L = GF(Integer(5)**Integer(8)).over(K, names=('b',)); (b,) = L._first_ngens(1); L
    Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base
    >>> L.base()
    Field in a with defining polynomial x^2 + z2*x + 4 over its base
    >>> L.base().base()
    Finite Field in z2 of size 5^2

The method `bases()` gives access to the complete list of rings in a tower:

Sage

    sage: L.bases()
    [Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base,
     Field in a with defining polynomial x^2 + z2*x + 4 over its base,
     Finite Field in z2 of size 5^2]

Python

    >>> from sage.all import *
    >>> L.bases()
    [Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base,
     Field in a with defining polynomial x^2 + z2*x + 4 over its base,
     Finite Field in z2 of size 5^2]

Once we have constructed an extension (or a tower of extensions), we have interesting methods attached to it. As a basic example, one can compute a basis of the top ring over any base in the tower:

Sage

    sage: L.basis_over(K)
    [1, b]
    sage: L.basis_over(F)
    [1, a, b, a*b]

[Python]

    >>> from sage.all import *
    >>> L.basis_over(K)
    [1, b]
    >>> L.basis_over(F)
    [1, a, b, a*b]

When the base is omitted, the default is the natural base of the extension:

Sage

    sage: L.basis_over()
    [1, b]

Python

    >>> from sage.all import *
    >>> L.basis_over()
    [1, b]

The method `sage.rings.ring_extension_element.RingExtensionWithBasis.vector()` computes the coordinates of an element according to the above basis:

Sage

    sage: u = a + 2*b + 3*a*b
    sage: u.vector()   # over K
    (a, 2 + 3*a)
    sage: u.vector(F)
    (0, 1, 2, 3)

[Python]

    >>> from sage.all import *
    >>> u = a + Integer(2)*b + Integer(3)*a*b
    >>> u.vector()   # over K
    (a, 2 + 3*a)
    >>> u.vector(F)
    (0, 1, 2, 3)

One can also compute traces and norms with respect to any base of the tower:

Sage

    sage: u.trace()           # over K
    (2*z2 + 1) + (2*z2 + 1)*a
    sage: u.trace(F)
    z2 + 1
    sage: u.trace().trace()   # over K, then over F
    z2 + 1
    sage: u.norm()            # over K
    (z2 + 1) + (4*z2 + 2)*a
    sage: u.norm(F)
    2*z2 + 2

Python

    >>> from sage.all import *
    >>> u.trace()           # over K
    (2*z2 + 1) + (2*z2 + 1)*a
    >>> u.trace(F)
    z2 + 1
    >>> u.trace().trace()   # over K, then over F
    z2 + 1
    >>> u.norm()            # over K
    (z2 + 1) + (4*z2 + 2)*a
    >>> u.norm(F)
    2*z2 + 2

And minimal polynomials:

Sage

    sage: u.minpoly()
    x^2 + ((3*z2 + 4) + (3*z2 + 4)*a)*x + (z2 + 1) + (4*z2 + 2)*a
    sage: u.minpoly(F)
    x^4 + (4*z2 + 4)*x^3 + x^2 + (z2 + 1)*x + 2*z2 + 2

[Python]

    >>> from sage.all import *
    >>> u.minpoly()
    x^2 + ((3*z2 + 4) + (3*z2 + 4)*a)*x + (z2 + 1) + (4*z2 + 2)*a
    >>> u.minpoly(F)
    x^4 + (4*z2 + 4)*x^3 + x^2 + (z2 + 1)*x + 2*z2 + 2

AUTHOR:

- Xavier Caruso (2019)

class sage.rings.ring_extension.RingExtensionFactory

  Bases: `UniqueFactory`

  Factory for ring extensions.

  create_key_and_extra_args(ring, defining_morphism=None, gens=None, names=None, constructors=None)

    Create a key and return it together with a list of constructors of the object.

    INPUT:

    - `ring` – a commutative ring

    - `defining_morphism` – a ring homomorphism or a commutative ring or `None` (default: `None`); the defining morphism of this extension or its base (if it coerces to `ring`)

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

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

    - `constructors` – list of constructors; each constructor is a pair \((class, arguments)\) where \(class\) is the class implementing the extension and \(arguments\) is the dictionary of arguments to pass in to init function

  create_object(version, key, **extra_args)

    Return the object associated to a given key.

class sage.rings.ring_extension.RingExtensionFractionField

  Bases: `RingExtension_generic`

  A class for ring extensions of the form ` extrm{Frac}(A)/A`.

  Element

    alias of `RingExtensionFractionFieldElement`

  ring()

    Return the ring whose fraction field is this extension.

    EXAMPLES:

    Sage

        sage: x = polygen(ZZ, 'x')
        sage: A.<a> = ZZ.extension(x^2 - 2)
        sage: OK = A.over()
        sage: K = OK.fraction_field(); K
        Fraction Field of
         Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base
        sage: K.ring()
        Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base
        sage: K.ring() is OK
        True

    Python

        >>> from sage.all import *
        >>> x = polygen(ZZ, 'x')
        >>> A = ZZ.extension(x**Integer(2) - Integer(2), names=('a',)); (a,) = A._first_ngens(1)
        >>> OK = A.over()
        >>> K = OK.fraction_field(); K
        Fraction Field of
         Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base
        >>> K.ring()
        Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base
        >>> K.ring() is OK
        True

class sage.rings.ring_extension.RingExtensionWithBasis

  Bases: `RingExtension_generic`

  A class for finite free ring extensions equipped with a basis.

  Element

    alias of `RingExtensionWithBasisElement`

  basis_over(base=None)

    Return a basis of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension)

    EXAMPLES:

    Sage

        sage: F.<a> = GF(5^2).over()  # over GF(5)
        sage: K.<b> = GF(5^4).over(F)
        sage: L.<c> = GF(5^12).over(K)
        sage: L.basis_over(K)
        [1, c, c^2]
        sage: L.basis_over(F)
        [1, b, c, b*c, c^2, b*c^2]
        sage: L.basis_over(GF(5))
        [1, a, b, a*b, c, a*c, b*c, a*b*c, c^2, a*c^2, b*c^2, a*b*c^2]

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = F._first_ngens(1)# over GF(5)
        >>> K = GF(Integer(5)**Integer(4)).over(F, names=('b',)); (b,) = K._first_ngens(1)
        >>> L = GF(Integer(5)**Integer(12)).over(K, names=('c',)); (c,) = L._first_ngens(1)
        >>> L.basis_over(K)
        [1, c, c^2]
        >>> L.basis_over(F)
        [1, b, c, b*c, c^2, b*c^2]
        >>> L.basis_over(GF(Integer(5)))
        [1, a, b, a*b, c, a*c, b*c, a*b*c, c^2, a*c^2, b*c^2, a*b*c^2]

    If `base` is omitted, it is set to its default which is the base of the extension:

    Sage

        sage: L.basis_over()
        [1, c, c^2]

        sage: K.basis_over()
        [1, b]

    [Python]

        >>> from sage.all import *
        >>> L.basis_over()
        [1, c, c^2]

        >>> K.basis_over()
        [1, b]

    Note that `base` must be an explicit base over which the extension has been defined (as listed by the method `bases()`):

    Sage

        sage: L.degree_over(GF(5^6))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field in z6 of size 5^6

    Python

        >>> from sage.all import *
        >>> L.degree_over(GF(Integer(5)**Integer(6)))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field in z6 of size 5^6

  fraction_field(extend_base=False)

    Return the fraction field of this extension.

    INPUT:

    - `extend_base` – boolean (default: `False`)

    If `extend_base` is `False`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except is \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.

    If `extend_base` is `True`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).

    EXAMPLES:

    Sage

        sage: x = polygen(ZZ, 'x')
        sage: A.<a> = ZZ.extension(x^2 - 5)
        sage: OK = A.over()   # over ZZ
        sage: OK
        Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        sage: K1.bases()
        [Fraction Field of Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        sage: K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Python

        >>> from sage.all import *
        >>> x = polygen(ZZ, 'x')
        >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1)
        >>> OK = A.over()   # over ZZ
        >>> OK
        Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        >>> K1.bases()
        [Fraction Field of Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        >>> K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Note that there is no coercion map between \(K_1\) and \(K_2\):

    Sage

        sage: K1.has_coerce_map_from(K2)
        False
        sage: K2.has_coerce_map_from(K1)
        False

    [Python]

        >>> from sage.all import *
        >>> K1.has_coerce_map_from(K2)
        False
        >>> K2.has_coerce_map_from(K1)
        False

    We check that when the extension is a field, its fraction field does not change:

    Sage

        sage: K1.fraction_field() is K1
        True
        sage: K2.fraction_field() is K2
        True

    Python

        >>> from sage.all import *
        >>> K1.fraction_field() is K1
        True
        >>> K2.fraction_field() is K2
        True

  free_module(base=None, map=True)

    Return a free module V over `base` which is isomorphic to this ring

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    - `map` – boolean (default: `True`); whether to return isomorphisms between this ring and V

    OUTPUT:

    - A finite-rank free module V over `base`

    - The isomorphism from V to this ring corresponding to the basis output by the method `basis_over()` (only included if `map` is `True`)

    - The reverse isomorphism of the isomorphism above (only included if `map` is `True`)

    EXAMPLES:

    Sage

        sage: F = GF(11)
        sage: K.<a> = GF(11^2).over()
        sage: L.<b> = GF(11^6).over(K)

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(11))
        >>> K = GF(Integer(11)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)
        >>> L = GF(Integer(11)**Integer(6)).over(K, names=('b',)); (b,) = L._first_ngens(1)

    Forgetting a part of the multiplicative structure, the field L can be viewed as a vector space of dimension 3 over K, equipped with a distinguished basis, namely \((1, b, b^2)\):

    Sage

        sage: V, i, j = L.free_module(K)
        sage: V
        Vector space of dimension 3 over
         Field in a with defining polynomial x^2 + 7*x + 2 over its base
        sage: i
        Generic map:
          From: Vector space of dimension 3 over
                Field in a with defining polynomial x^2 + 7*x + 2 over its base
          To:   Field in b with defining polynomial
                x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base
        sage: j
        Generic map:
          From: Field in b with defining polynomial
                x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base
          To:   Vector space of dimension 3 over
                Field in a with defining polynomial x^2 + 7*x + 2 over its base
        sage: j(b)
        (0, 1, 0)
        sage: i((1, a, a+1))
        1 + a*b + (1 + a)*b^2

    [Python]

        >>> from sage.all import *
        >>> V, i, j = L.free_module(K)
        >>> V
        Vector space of dimension 3 over
         Field in a with defining polynomial x^2 + 7*x + 2 over its base
        >>> i
        Generic map:
          From: Vector space of dimension 3 over
                Field in a with defining polynomial x^2 + 7*x + 2 over its base
          To:   Field in b with defining polynomial
                x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base
        >>> j
        Generic map:
          From: Field in b with defining polynomial
                x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base
          To:   Vector space of dimension 3 over
                Field in a with defining polynomial x^2 + 7*x + 2 over its base
        >>> j(b)
        (0, 1, 0)
        >>> i((Integer(1), a, a+Integer(1)))
        1 + a*b + (1 + a)*b^2

    Similarly, one can view L as a F-vector space of dimension 6:

    Sage

        sage: V, i, j, = L.free_module(F)
        sage: V
        Vector space of dimension 6 over Finite Field of size 11

    Python

        >>> from sage.all import *
        >>> V, i, j, = L.free_module(F)
        >>> V
        Vector space of dimension 6 over Finite Field of size 11

    In this case, the isomorphisms between \(V\) and \(L\) are given by the basis \((1, a, b, ab, b^2, ab^2)\):

    > sage: j(a*b) (0, 0, 0, 1, 0, 0) sage: i((1,2,3,4,5,6)) (1 + 2*a) + (3 + 4*a)*b + (5 + 6*a)*b^2

    When `base` is omitted, the default is the base of this extension:

    Sage

        sage: L.free_module(map=False)
        Vector space of dimension 3 over
         Field in a with defining polynomial x^2 + 7*x + 2 over its base

    [Python]

        >>> from sage.all import *
        >>> L.free_module(map=False)
        Vector space of dimension 3 over
         Field in a with defining polynomial x^2 + 7*x + 2 over its base

    Note that `base` must be an explicit base over which the extension has been defined (as listed by the method `bases()`):

    Sage

        sage: L.degree(GF(11^3))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field in z3 of size 11^3

    Python

        >>> from sage.all import *
        >>> L.degree(GF(Integer(11)**Integer(3)))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field in z3 of size 11^3

class sage.rings.ring_extension.RingExtensionWithGen

  Bases: `RingExtensionWithBasis`

  A class for finite free ring extensions generated by a single element

  fraction_field(extend_base=False)

    Return the fraction field of this extension.

    INPUT:

    - `extend_base` – boolean (default: `False`)

    If `extend_base` is `False`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except is \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.

    If `extend_base` is `True`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).

    EXAMPLES:

    Sage

        sage: x = polygen(ZZ, 'x')
        sage: A.<a> = ZZ.extension(x^2 - 5)
        sage: OK = A.over()   # over ZZ
        sage: OK
        Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        sage: K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K1.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        sage: K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Python

        >>> from sage.all import *
        >>> x = polygen(ZZ, 'x')
        >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1)
        >>> OK = A.over()   # over ZZ
        >>> OK
        Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        >>> K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K1.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
          with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        >>> K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
          in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Note that there is no coercion map between \(K_1\) and \(K_2\):

    Sage

        sage: K1.has_coerce_map_from(K2)
        False
        sage: K2.has_coerce_map_from(K1)
        False

    [Python]

        >>> from sage.all import *
        >>> K1.has_coerce_map_from(K2)
        False
        >>> K2.has_coerce_map_from(K1)
        False

    We check that when the extension is a field, its fraction field does not change:

    Sage

        sage: K1.fraction_field() is K1
        True
        sage: K2.fraction_field() is K2
        True

    Python

        >>> from sage.all import *
        >>> K1.fraction_field() is K1
        True
        >>> K2.fraction_field() is K2
        True

  gens(base=None)

    Return the generators of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: K.<a> = GF(5^2).over()  # over GF(5)
        sage: K.gens()
        (a,)
        sage: L.<b> = GF(5^4).over(K)
        sage: L.gens()
        (b,)
        sage: L.gens(GF(5))
        (b, a)

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5)
        >>> K.gens()
        (a,)
        >>> L = GF(Integer(5)**Integer(4)).over(K, names=('b',)); (b,) = L._first_ngens(1)
        >>> L.gens()
        (b,)
        >>> L.gens(GF(Integer(5)))
        (b, a)

  modulus(var='x')

    Return the defining polynomial of this extension, that is the minimal polynomial of the given generator of this extension.

    INPUT:

    - `var` – a variable name (default: `x`)

    EXAMPLES:

    Sage

        sage: K.<u> = GF(7^10).over(GF(7^2)); K
        Field in u with defining polynomial x^5 + (6*z2 + 4)*x^4
         + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 over its base
        sage: P = K.modulus(); P
        x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2
        sage: P(u)
        0

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(7)**Integer(10)).over(GF(Integer(7)**Integer(2)), names=('u',)); (u,) = K._first_ngens(1); K
        Field in u with defining polynomial x^5 + (6*z2 + 4)*x^4
         + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 over its base
        >>> P = K.modulus(); P
        x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2
        >>> P(u)
        0

    We can use a different variable name:

    Sage

        sage: K.modulus('y')
        y^5 + (6*z2 + 4)*y^4 + (3*z2 + 5)*y^3 + (2*z2 + 2)*y^2 + 4*y + 6*z2

    [Python]

        >>> from sage.all import *
        >>> K.modulus('y')
        y^5 + (6*z2 + 4)*y^4 + (3*z2 + 5)*y^3 + (2*z2 + 2)*y^2 + 4*y + 6*z2

class sage.rings.ring_extension.RingExtension_generic

  Bases: `Parent`

  A generic class for all ring extensions.

  Element

    alias of `RingExtensionElement`

  absolute_base()

    Return the absolute base of this extension.

    By definition, the absolute base of an iterated extension \(K_n/\cdots K_2/K_1\) is the ring \(K_1\).

    EXAMPLES:

    Sage

        sage: F = GF(5^2).over()   # over GF(5)
        sage: K = GF(5^4).over(F)
        sage: L = GF(5^12).over(K)
        sage: F.absolute_base()
        Finite Field of size 5
        sage: K.absolute_base()
        Finite Field of size 5
        sage: L.absolute_base()
        Finite Field of size 5

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2)).over()   # over GF(5)
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> L = GF(Integer(5)**Integer(12)).over(K)
        >>> F.absolute_base()
        Finite Field of size 5
        >>> K.absolute_base()
        Finite Field of size 5
        >>> L.absolute_base()
        Finite Field of size 5

    See also

    `base()`, `bases()`, `is_defined_over()`

  absolute_degree()

    Return the degree of this extension over its absolute base.

    EXAMPLES:

    Sage

        sage: A = GF(5^4).over(GF(5^2))
        sage: B = GF(5^12).over(A)
        sage: A.absolute_degree()
        2
        sage: B.absolute_degree()
        6

    Python

        >>> from sage.all import *
        >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))
        >>> B = GF(Integer(5)**Integer(12)).over(A)
        >>> A.absolute_degree()
        2
        >>> B.absolute_degree()
        6

    See also

    `degree()`, `relative_degree()`

  backend(force=False)

    Return the backend of this extension.

    INPUT:

    - `force` – boolean (default: `False`); if `False`, raise an error if the backend is not exposed

    EXAMPLES:

    Sage

        sage: K = GF(5^3)
        sage: E = K.over()
        sage: E
        Field in z3 with defining polynomial x^3 + 3*x + 3 over its base
        sage: E.backend()
        Finite Field in z3 of size 5^3
        sage: E.backend() is K
        True

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(3))
        >>> E = K.over()
        >>> E
        Field in z3 with defining polynomial x^3 + 3*x + 3 over its base
        >>> E.backend()
        Finite Field in z3 of size 5^3
        >>> E.backend() is K
        True

  base()

    Return the base of this extension.

    EXAMPLES:

    Sage

        sage: F = GF(5^2)
        sage: K = GF(5^4).over(F)
        sage: K.base()
        Finite Field in z2 of size 5^2

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2))
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> K.base()
        Finite Field in z2 of size 5^2

    In case of iterated extensions, the base is itself an extension:

    Sage

        sage: L = GF(5^8).over(K)
        sage: L.base()
        Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
        sage: L.base() is K
        True

    [Python]

        >>> from sage.all import *
        >>> L = GF(Integer(5)**Integer(8)).over(K)
        >>> L.base()
        Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
        >>> L.base() is K
        True

    See also

    `bases()`, `absolute_base()`, `is_defined_over()`

  bases()

    Return the list of successive bases of this extension (including itself).

    EXAMPLES:

    Sage

        sage: F = GF(5^2).over()  # over GF(5)
        sage: K = GF(5^4).over(F)
        sage: L = GF(5^12).over(K)
        sage: F.bases()
        [Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]
        sage: K.bases()
        [Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base,
         Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]
        sage: L.bases()
        [Field in z12 with defining polynomial
          x^3 + (1 + (2 - z2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base,
         Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base,
         Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2)).over()  # over GF(5)
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> L = GF(Integer(5)**Integer(12)).over(K)
        >>> F.bases()
        [Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]
        >>> K.bases()
        [Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base,
         Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]
        >>> L.bases()
        [Field in z12 with defining polynomial
          x^3 + (1 + (2 - z2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base,
         Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base,
         Field in z2 with defining polynomial x^2 + 4*x + 2 over its base,
         Finite Field of size 5]

    See also

    `base()`, `absolute_base()`, `is_defined_over()`

  characteristic()

    Return the characteristic of the extension as a ring.

    OUTPUT: a prime number or zero

    EXAMPLES:

    Sage

        sage: F = GF(5^2).over()   # over GF(5)
        sage: K = GF(5^4).over(F)
        sage: L = GF(5^12).over(K)
        sage: F.characteristic()
        5
        sage: K.characteristic()
        5
        sage: L.characteristic()
        5

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2)).over()   # over GF(5)
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> L = GF(Integer(5)**Integer(12)).over(K)
        >>> F.characteristic()
        5
        >>> K.characteristic()
        5
        >>> L.characteristic()
        5

    Sage

        sage: F = RR.over(ZZ)
        sage: F.characteristic()
        0

    [Python]

        >>> from sage.all import *
        >>> F = RR.over(ZZ)
        >>> F.characteristic()
        0

    Sage

        sage: F = GF(11)
        sage: A.<x> = F[]
        sage: K = Frac(F).over(F)
        sage: K.characteristic()
        11

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(11))
        >>> A = F['x']; (x,) = A._first_ngens(1)
        >>> K = Frac(F).over(F)
        >>> K.characteristic()
        11

    Sage

        sage: E = GF(7).over(ZZ)
        sage: E.characteristic()
        7

    [Python]

        >>> from sage.all import *
        >>> E = GF(Integer(7)).over(ZZ)
        >>> E.characteristic()
        7

  construction()

    Return the functorial construction of this extension, if defined.

    EXAMPLES:

    Sage

        sage: E = GF(5^3).over()
        sage: E.construction()

    Python

        >>> from sage.all import *
        >>> E = GF(Integer(5)**Integer(3)).over()
        >>> E.construction()

  defining_morphism(base=None)

    Return the defining morphism of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: F = GF(5^2)
        sage: K = GF(5^4).over(F)
        sage: L = GF(5^12).over(K)
        sage: K.defining_morphism()
        Ring morphism:
          From: Finite Field in z2 of size 5^2
          To:   Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
          Defn: z2 |--> z2
        sage: L.defining_morphism()
        Ring morphism:
          From: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
          To:   Field in z12 with defining polynomial
                x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
          Defn: z4 |--> z4

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2))
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> L = GF(Integer(5)**Integer(12)).over(K)
        >>> K.defining_morphism()
        Ring morphism:
          From: Finite Field in z2 of size 5^2
          To:   Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
          Defn: z2 |--> z2
        >>> L.defining_morphism()
        Ring morphism:
          From: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
          To:   Field in z12 with defining polynomial
                x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
          Defn: z4 |--> z4

    One can also pass in a base over which the extension is explicitly defined (see also `is_defined_over()`):

    Sage

        sage: L.defining_morphism(F)
        Ring morphism:
          From: Finite Field in z2 of size 5^2
          To:   Field in z12 with defining polynomial
                x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
          Defn: z2 |--> z2
        sage: L.defining_morphism(GF(5))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

    [Python]

        >>> from sage.all import *
        >>> L.defining_morphism(F)
        Ring morphism:
          From: Finite Field in z2 of size 5^2
          To:   Field in z12 with defining polynomial
                x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base
          Defn: z2 |--> z2
        >>> L.defining_morphism(GF(Integer(5)))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

  degree(base)

    Return the degree of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension)

    EXAMPLES:

    Sage

        sage: A = GF(5^4).over(GF(5^2))
        sage: B = GF(5^12).over(A)
        sage: A.degree(GF(5^2))
        2
        sage: B.degree(A)
        3
        sage: B.degree(GF(5^2))
        6

    Python

        >>> from sage.all import *
        >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))
        >>> B = GF(Integer(5)**Integer(12)).over(A)
        >>> A.degree(GF(Integer(5)**Integer(2)))
        2
        >>> B.degree(A)
        3
        >>> B.degree(GF(Integer(5)**Integer(2)))
        6

    Note that `base` must be an explicit base over which the extension has been defined (as listed by the method `bases()`):

    Sage

        sage: A.degree(GF(5))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

    [Python]

        >>> from sage.all import *
        >>> A.degree(GF(Integer(5)))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

    See also

    `relative_degree()`, `absolute_degree()`

  degree_over(base=None)

    Return the degree of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: F = GF(5^2)
        sage: K = GF(5^4).over(F)
        sage: L = GF(5^12).over(K)
        sage: K.degree_over(F)
        2
        sage: L.degree_over(K)
        3
        sage: L.degree_over(F)
        6

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(5)**Integer(2))
        >>> K = GF(Integer(5)**Integer(4)).over(F)
        >>> L = GF(Integer(5)**Integer(12)).over(K)
        >>> K.degree_over(F)
        2
        >>> L.degree_over(K)
        3
        >>> L.degree_over(F)
        6

    If `base` is omitted, the degree is computed over the base of the extension:

    Sage

        sage: K.degree_over()
        2
        sage: L.degree_over()
        3

    [Python]

        >>> from sage.all import *
        >>> K.degree_over()
        2
        >>> L.degree_over()
        3

    Note that `base` must be an explicit base over which the extension has been defined (as listed by the method `bases()`):

    Sage

        sage: K.degree_over(GF(5))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

    Python

        >>> from sage.all import *
        >>> K.degree_over(GF(Integer(5)))
        Traceback (most recent call last):
        ...
        ValueError: not (explicitly) defined over Finite Field of size 5

  fraction_field(extend_base=False)

    Return the fraction field of this extension.

    INPUT:

    - `extend_base` – boolean (default: `False`)

    If `extend_base` is `False`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except if \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.

    If `extend_base` is `True`, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).

    EXAMPLES:

    Sage

        sage: x = polygen(ZZ, 'x')
        sage: A.<a> = ZZ.extension(x^2 - 5)
        sage: OK = A.over()   # over ZZ
        sage: OK
        Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        sage: K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K1.bases()
        [Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        sage: K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        sage: K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Python

        >>> from sage.all import *
        >>> x = polygen(ZZ, 'x')
        >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1)
        >>> OK = A.over()   # over ZZ
        >>> OK
        Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base
        >>> K1 = OK.fraction_field(); K1
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K1.bases()
        [Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base,
         Order of conductor 2 generated by a in Number Field in a
         with defining polynomial x^2 - 5 over its base,
         Integer Ring]
        >>> K2 = OK.fraction_field(extend_base=True); K2
        Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base
        >>> K2.bases()
        [Fraction Field of Order of conductor 2 generated by a
         in Number Field in a with defining polynomial x^2 - 5 over its base,
         Rational Field]

    Note that there is no coercion between \(K_1\) and \(K_2\):

    Sage

        sage: K1.has_coerce_map_from(K2)
        False
        sage: K2.has_coerce_map_from(K1)
        False

    [Python]

        >>> from sage.all import *
        >>> K1.has_coerce_map_from(K2)
        False
        >>> K2.has_coerce_map_from(K1)
        False

    We check that when the extension is a field, its fraction field does not change:

    Sage

        sage: K1.fraction_field() is K1
        True
        sage: K2.fraction_field() is K2
        True

    Python

        >>> from sage.all import *
        >>> K1.fraction_field() is K1
        True
        >>> K2.fraction_field() is K2
        True

  from_base_ring(r)

    Return the canonical embedding of `r` into this extension.

    INPUT:

    - `r` – an element of the base of the ring of this extension

    EXAMPLES:

    Sage

        sage: k = GF(5)
        sage: K.<u> = GF(5^2).over(k)
        sage: L.<v> = GF(5^4).over(K)
        sage: x = L.from_base_ring(k(2)); x
        2
        sage: x.parent()
        Field in v with defining polynomial x^2 + (3 - u)*x + u over its base
        sage: x = L.from_base_ring(u); x
        u
        sage: x.parent()
        Field in v with defining polynomial x^2 + (3 - u)*x + u over its base

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5))
        >>> K = GF(Integer(5)**Integer(2)).over(k, names=('u',)); (u,) = K._first_ngens(1)
        >>> L = GF(Integer(5)**Integer(4)).over(K, names=('v',)); (v,) = L._first_ngens(1)
        >>> x = L.from_base_ring(k(Integer(2))); x
        2
        >>> x.parent()
        Field in v with defining polynomial x^2 + (3 - u)*x + u over its base
        >>> x = L.from_base_ring(u); x
        u
        >>> x.parent()
        Field in v with defining polynomial x^2 + (3 - u)*x + u over its base

  gen()

    Return the first generator of this extension.

    EXAMPLES:

    Sage

        sage: K = GF(5^2).over()   # over GF(5)
        sage: x = K.gen(); x
        z2

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over()   # over GF(5)
        >>> x = K.gen(); x
        z2

    Observe that the generator lives in the extension:

    Sage

        sage: x.parent()
        Field in z2 with defining polynomial x^2 + 4*x + 2 over its base
        sage: x.parent() is K
        True

    [Python]

        >>> from sage.all import *
        >>> x.parent()
        Field in z2 with defining polynomial x^2 + 4*x + 2 over its base
        >>> x.parent() is K
        True

  gens(base=None)

    Return the generators of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`); if omitted, use the base of this extension

    EXAMPLES:

    Sage

        sage: K.<a> = GF(5^2).over()  # over GF(5)
        sage: K.gens()
        (a,)
        sage: L.<b> = GF(5^4).over(K)
        sage: L.gens()
        (b,)
        sage: L.gens(GF(5))
        (b, a)

        sage: S.<x> = QQ[]
        sage: T.<y> = S[]
        sage: T.over(S).gens()
        (y,)
        sage: T.over(QQ).gens()
        (y, x)

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5)
        >>> K.gens()
        (a,)
        >>> L = GF(Integer(5)**Integer(4)).over(K, names=('b',)); (b,) = L._first_ngens(1)
        >>> L.gens()
        (b,)
        >>> L.gens(GF(Integer(5)))
        (b, a)

        >>> S = QQ['x']; (x,) = S._first_ngens(1)
        >>> T = S['y']; (y,) = T._first_ngens(1)
        >>> T.over(S).gens()
        (y,)
        >>> T.over(QQ).gens()
        (y, x)

  hom(im_gens, codomain=None, base_map=None, category=None, check=True)

    Return the unique homomorphism from this extension to `codomain` that sends `self.gens()` to the entries of `im_gens` and induces the map `base_map` on the base ring.

    INPUT:

    - `im_gens` – the images of the generators of this extension

    - `codomain` – the codomain of the homomorphism; if omitted, it is set to the smallest parent containing all the entries of `im_gens`

    - `base_map` – a map from one of the bases of this extension into something that coerces into the codomain; if omitted, coercion maps are used

    - `category` – the category of the resulting morphism

    - `check` – boolean (default: `True`); whether to verify that the images of generators extend to define a map (using only canonical coercions)

    EXAMPLES:

    Sage

        sage: K.<a> = GF(5^2).over()    # over GF(5)
        sage: L.<b> = GF(5^6).over(K)

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5)
        >>> L = GF(Integer(5)**Integer(6)).over(K, names=('b',)); (b,) = L._first_ngens(1)

    We define (by hand) the relative Frobenius endomorphism of the extension \(L/K\):

    Sage

        sage: L.hom([b^25])
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> 2 + 2*a*b + (2 - a)*b^2

    [Python]

        >>> from sage.all import *
        >>> L.hom([b**Integer(25)])
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> 2 + 2*a*b + (2 - a)*b^2

    Defining the absolute Frobenius of \(L\) is a bit more complicated because it is not a homomorphism of \(K\)-algebras. For this reason, the construction `L.hom([b^5])` fails:

    Sage

        sage: L.hom([b^5])
        Traceback (most recent call last):
        ...
        ValueError: images do not define a valid homomorphism

    Python

        >>> from sage.all import *
        >>> L.hom([b**Integer(5)])
        Traceback (most recent call last):
        ...
        ValueError: images do not define a valid homomorphism

    What we need is to specify a base map:

    Sage

        sage: FrobK = K.hom([a^5])
        sage: FrobL = L.hom([b^5], base_map=FrobK); FrobL
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2
                with map on base ring:
                a |--> 1 - a

    [Python]

        >>> from sage.all import *
        >>> FrobK = K.hom([a**Integer(5)])
        >>> FrobL = L.hom([b**Integer(5)], base_map=FrobK); FrobL
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2
                with map on base ring:
                a |--> 1 - a

    As a shortcut, we may use the following construction:

    Sage

        sage: phi = L.hom([b^5, a^5]); phi
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2
                with map on base ring:
                a |--> 1 - a
        sage: phi == FrobL
        True

    Python

        >>> from sage.all import *
        >>> phi = L.hom([b**Integer(5), a**Integer(5)]); phi
        Ring endomorphism of
         Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base
          Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2
                with map on base ring:
                a |--> 1 - a
        >>> phi == FrobL
        True

  is_defined_over(base)

    Return whether or not `base` is one of the bases of this extension.

    INPUT:

    - `base` – a commutative ring, which might be itself an extension

    EXAMPLES:

    Sage

        sage: A = GF(5^4).over(GF(5^2))
        sage: B = GF(5^12).over(A)
        sage: A.is_defined_over(GF(5^2))
        True
        sage: A.is_defined_over(GF(5))
        False

        sage: B.is_defined_over(A)
        True
        sage: B.is_defined_over(GF(5^4))
        True
        sage: B.is_defined_over(GF(5^2))
        True
        sage: B.is_defined_over(GF(5))
        False

    Python

        >>> from sage.all import *
        >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))
        >>> B = GF(Integer(5)**Integer(12)).over(A)
        >>> A.is_defined_over(GF(Integer(5)**Integer(2)))
        True
        >>> A.is_defined_over(GF(Integer(5)))
        False

        >>> B.is_defined_over(A)
        True
        >>> B.is_defined_over(GF(Integer(5)**Integer(4)))
        True
        >>> B.is_defined_over(GF(Integer(5)**Integer(2)))
        True
        >>> B.is_defined_over(GF(Integer(5)))
        False

    Note that an extension is defined over itself:

    Sage

        sage: A.is_defined_over(A)
        True
        sage: A.is_defined_over(GF(5^4))
        True

    [Python]

        >>> from sage.all import *
        >>> A.is_defined_over(A)
        True
        >>> A.is_defined_over(GF(Integer(5)**Integer(4)))
        True

    See also

    `base()`, `bases()`, `absolute_base()`

  is_field(proof=True)

    Return whether or not this extension is a field.

    INPUT:

    - `proof` – boolean (default: `False`)

    EXAMPLES:

    Sage

        sage: K = GF(5^5).over()  # over GF(5)
        sage: K.is_field()
        True

        sage: S.<x> = QQ[]
        sage: A = S.over(QQ)
        sage: A.is_field()
        False

        sage: B = A.fraction_field()
        sage: B.is_field()
        True

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(5)).over()  # over GF(5)
        >>> K.is_field()
        True

        >>> S = QQ['x']; (x,) = S._first_ngens(1)
        >>> A = S.over(QQ)
        >>> A.is_field()
        False

        >>> B = A.fraction_field()
        >>> B.is_field()
        True

  is_finite_over(base=None)

    Return whether or not this extension is finite over `base` (as a module).

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: K = GF(5^2).over()  # over GF(5)
        sage: L = GF(5^4).over(K)
        sage: L.is_finite_over(K)
        True
        sage: L.is_finite_over(GF(5))
        True

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over()  # over GF(5)
        >>> L = GF(Integer(5)**Integer(4)).over(K)
        >>> L.is_finite_over(K)
        True
        >>> L.is_finite_over(GF(Integer(5)))
        True

    If `base` is omitted, it is set to its default which is the base of the extension:

    Sage

        sage: L.is_finite_over()
        True

    [Python]

        >>> from sage.all import *
        >>> L.is_finite_over()
        True

  is_free_over(base=None)

    Return `True` if this extension is free (as a module) over `base`

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: K = GF(5^2).over()  # over GF(5)
        sage: L = GF(5^4).over(K)
        sage: L.is_free_over(K)
        True
        sage: L.is_free_over(GF(5))
        True

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over()  # over GF(5)
        >>> L = GF(Integer(5)**Integer(4)).over(K)
        >>> L.is_free_over(K)
        True
        >>> L.is_free_over(GF(Integer(5)))
        True

    If `base` is omitted, it is set to its default which is the base of the extension:

    Sage

        sage: L.is_free_over()
        True

    [Python]

        >>> from sage.all import *
        >>> L.is_free_over()
        True

  ngens(base=None)

    Return the number of generators of this extension over `base`.

    INPUT:

    - `base` – a commutative ring (which might be itself an extension) or `None` (default: `None`)

    EXAMPLES:

    Sage

        sage: K = GF(5^2).over()   # over GF(5)
        sage: K.gens()
        (z2,)
        sage: K.ngens()
        1
        sage: L = GF(5^4).over(K)
        sage: L.gens(GF(5))
        (z4, z2)
        sage: L.ngens(GF(5))
        2

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over()   # over GF(5)
        >>> K.gens()
        (z2,)
        >>> K.ngens()
        1
        >>> L = GF(Integer(5)**Integer(4)).over(K)
        >>> L.gens(GF(Integer(5)))
        (z4, z2)
        >>> L.ngens(GF(Integer(5)))
        2

  print_options(**options)

    Update the printing options of this extension.

    INPUT:

    - `over` – integer or `Infinity` (default: `0`); the maximum number of bases included in the printing of this extension

    - `base` – a base over which this extension is finite free; elements in this extension will be printed as a linear combinaison of a basis of this extension over the given base

    EXAMPLES:

    Sage

        sage: A.<a> = GF(5^2).over()   # over GF(5)
        sage: B.<b> = GF(5^4).over(A)
        sage: C.<c> = GF(5^12).over(B)
        sage: D.<d> = GF(5^24).over(C)

    Python

        >>> from sage.all import *
        >>> A = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = A._first_ngens(1)# over GF(5)
        >>> B = GF(Integer(5)**Integer(4)).over(A, names=('b',)); (b,) = B._first_ngens(1)
        >>> C = GF(Integer(5)**Integer(12)).over(B, names=('c',)); (c,) = C._first_ngens(1)
        >>> D = GF(Integer(5)**Integer(24)).over(C, names=('d',)); (d,) = D._first_ngens(1)

    Observe what happens when we modify the option `over`:

    Sage

        sage: D
        Field in d with defining polynomial
         x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over its base
        sage: D.print_options(over=2)
        sage: D
        Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over
        Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over
        Field in b with defining polynomial x^2 + (3 - a)*x + a over its base
        sage: D.print_options(over=Infinity)
        sage: D
        Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over
        Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over
        Field in b with defining polynomial x^2 + (3 - a)*x + a over
        Field in a with defining polynomial x^2 + 4*x + 2 over
        Finite Field of size 5

    [Python]

        >>> from sage.all import *
        >>> D
        Field in d with defining polynomial
         x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over its base
        >>> D.print_options(over=Integer(2))
        >>> D
        Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over
        Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over
        Field in b with defining polynomial x^2 + (3 - a)*x + a over its base
        >>> D.print_options(over=Infinity)
        >>> D
        Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over
        Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over
        Field in b with defining polynomial x^2 + (3 - a)*x + a over
        Field in a with defining polynomial x^2 + 4*x + 2 over
        Finite Field of size 5

    Now the option `base`:

    Sage

        sage: d^2
        -c + ((-1 + a) + ((-1 + 3*a) + b)*c + ((3 - a) + (-1 + a)*b)*c^2)*d
        sage: D.basis_over(B)
        [1, c, c^2, d, c*d, c^2*d]
        sage: D.print_options(base=B)
        sage: d^2
        -c + (-1 + a)*d + ((-1 + 3*a) + b)*c*d + ((3 - a) + (-1 + a)*b)*c^2*d
        sage: D.basis_over(A)
        [1, b, c, b*c, c^2, b*c^2, d, b*d, c*d, b*c*d, c^2*d, b*c^2*d]
        sage: D.print_options(base=A)
        sage: d^2
        -c + (-1 + a)*d + (-1 + 3*a)*c*d + b*c*d + (3 - a)*c^2*d + (-1 + a)*b*c^2*d

    Python

        >>> from sage.all import *
        >>> d**Integer(2)
        -c + ((-1 + a) + ((-1 + 3*a) + b)*c + ((3 - a) + (-1 + a)*b)*c^2)*d
        >>> D.basis_over(B)
        [1, c, c^2, d, c*d, c^2*d]
        >>> D.print_options(base=B)
        >>> d**Integer(2)
        -c + (-1 + a)*d + ((-1 + 3*a) + b)*c*d + ((3 - a) + (-1 + a)*b)*c^2*d
        >>> D.basis_over(A)
        [1, b, c, b*c, c^2, b*c^2, d, b*d, c*d, b*c*d, c^2*d, b*c^2*d]
        >>> D.print_options(base=A)
        >>> d**Integer(2)
        -c + (-1 + a)*d + (-1 + 3*a)*c*d + b*c*d + (3 - a)*c^2*d + (-1 + a)*b*c^2*d

  random_element()

    Return a random element in this extension.

    EXAMPLES:

    Sage

        sage: K = GF(5^2).over()   # over GF(5)
        sage: x = K.random_element(); x   # random
        3 + z2
        sage: x.parent()
        Field in z2 with defining polynomial x^2 + 4*x + 2 over its base
        sage: x.parent() is K
        True

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5)**Integer(2)).over()   # over GF(5)
        >>> x = K.random_element(); x   # random
        3 + z2
        >>> x.parent()
        Field in z2 with defining polynomial x^2 + 4*x + 2 over its base
        >>> x.parent() is K
        True

  relative_degree()

    Return the degree of this extension over its base.

    EXAMPLES:

    Sage

        sage: A = GF(5^4).over(GF(5^2))
        sage: A.relative_degree()
        2

    Python

        >>> from sage.all import *
        >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))
        >>> A.relative_degree()
        2

    See also

    `degree()`, `absolute_degree()`

sage.rings.ring_extension.common_base(K, L, degree)

  Return a common base on which `K` and `L` are defined.

  INPUT:

  - `K` – a commutative ring

  - `L` – a commutative ring

  - `degree` – boolean; if `True`, return the degree of `K` and `L` over their common base

  EXAMPLES:

  Sage

      sage: from sage.rings.ring_extension import common_base

      sage: common_base(GF(5^3), GF(5^7), False)
      Finite Field of size 5
      sage: common_base(GF(5^3), GF(5^7), True)
      (Finite Field of size 5, 3, 7)

      sage: common_base(GF(5^3), GF(7^5), False)
      Traceback (most recent call last):
      ...
      NotImplementedError: unable to find a common base

  Python

      >>> from sage.all import *
      >>> from sage.rings.ring_extension import common_base

      >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(5)**Integer(7)), False)
      Finite Field of size 5
      >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(5)**Integer(7)), True)
      (Finite Field of size 5, 3, 7)

      >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(7)**Integer(5)), False)
      Traceback (most recent call last):
      ...
      NotImplementedError: unable to find a common base

  When `degree` is set to `True`, we only look up for bases on which both `K` and `L` are finite:

  Sage

      sage: S.<x> = QQ[]
      sage: common_base(S, QQ, False)
      Rational Field
      sage: common_base(S, QQ, True)
      Traceback (most recent call last):
      ...
      NotImplementedError: unable to find a common base

  [Python]

      >>> from sage.all import *
      >>> S = QQ['x']; (x,) = S._first_ngens(1)
      >>> common_base(S, QQ, False)
      Rational Field
      >>> common_base(S, QQ, True)
      Traceback (most recent call last):
      ...
      NotImplementedError: unable to find a common base

sage.rings.ring_extension.generators(ring, base)

  Return the generators of `ring` over `base`.

  INPUT:

  - `ring` – a commutative ring

  - `base` – a commutative ring

  EXAMPLES:

  Sage

      sage: from sage.rings.ring_extension import generators
      sage: S.<x> = QQ[]
      sage: T.<y> = S[]

      sage: generators(T, S)
      (y,)
      sage: generators(T, QQ)
      (y, x)

  Python

      >>> from sage.all import *
      >>> from sage.rings.ring_extension import generators
      >>> S = QQ['x']; (x,) = S._first_ngens(1)
      >>> T = S['y']; (y,) = T._first_ngens(1)

      >>> generators(T, S)
      (y,)
      >>> generators(T, QQ)
      (y, x)

sage.rings.ring_extension.tower_bases(ring, degree)

  Return the list of bases of `ring` (including itself); if degree is `True`, restrict to finite extensions and return in addition the degree of `ring` over each base.

  INPUT:

  - `ring` – a commutative ring

  - `degree` – boolean

  EXAMPLES:

  Sage

      sage: from sage.rings.ring_extension import tower_bases
      sage: S.<x> = QQ[]
      sage: T.<y> = S[]
      sage: tower_bases(T, False)
      ([Univariate Polynomial Ring in y over
         Univariate Polynomial Ring in x over Rational Field,
        Univariate Polynomial Ring in x over Rational Field,
        Rational Field],
       [])
      sage: tower_bases(T, True)
      ([Univariate Polynomial Ring in y over
         Univariate Polynomial Ring in x over Rational Field],
       [1])

      sage: K.<a> = Qq(5^2)
      sage: L.<w> = K.extension(x^3 - 5)
      sage: tower_bases(L, True)
      ([5-adic Eisenstein Extension Field in w defined by x^3 - 5 over its base field,
        5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2,
        5-adic Field with capped relative precision 20],
       [1, 3, 6])

  Python

      >>> from sage.all import *
      >>> from sage.rings.ring_extension import tower_bases
      >>> S = QQ['x']; (x,) = S._first_ngens(1)
      >>> T = S['y']; (y,) = T._first_ngens(1)
      >>> tower_bases(T, False)
      ([Univariate Polynomial Ring in y over
         Univariate Polynomial Ring in x over Rational Field,
        Univariate Polynomial Ring in x over Rational Field,
        Rational Field],
       [])
      >>> tower_bases(T, True)
      ([Univariate Polynomial Ring in y over
         Univariate Polynomial Ring in x over Rational Field],
       [1])

      >>> K = Qq(Integer(5)**Integer(2), names=('a',)); (a,) = K._first_ngens(1)
      >>> L = K.extension(x**Integer(3) - Integer(5), names=('w',)); (w,) = L._first_ngens(1)
      >>> tower_bases(L, True)
      ([5-adic Eisenstein Extension Field in w defined by x^3 - 5 over its base field,
        5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2,
        5-adic Field with capped relative precision 20],
       [1, 3, 6])

sage.rings.ring_extension.variable_names(ring, base)

  Return the variable names of the generators of `ring` over `base`.

  INPUT:

  - `ring` – a commutative ring

  - `base` – a commutative ring

  EXAMPLES:

  Sage

      sage: from sage.rings.ring_extension import variable_names
      sage: S.<x> = QQ[]
      sage: T.<y> = S[]

      sage: variable_names(T, S)
      ('y',)
      sage: variable_names(T, QQ)
      ('y', 'x')

  Python

      >>> from sage.all import *
      >>> from sage.rings.ring_extension import variable_names
      >>> S = QQ['x']; (x,) = S._first_ngens(1)
      >>> T = S['y']; (y,) = T._first_ngens(1)

      >>> variable_names(T, S)
      ('y',)
      >>> variable_names(T, QQ)
      ('y', 'x')