Beispiel #1
0
def make_function_field(K):
    r"""
    Return the function field isomorphic to this field, an isomorphism,
    and its inverse.

    INPUT:

    - ``K`` -- a field

    OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field,
    `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`.

    It is assumed that `K` is either the fraction field of a polynomial ring
    over a finite field `k`, or a finite simple extension of such a field.

    In the first case, `F=k_1(x)` is a rational function field over a finite
    field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`.
    In the second case, `F` is a finite simple extension of a rational function
    field as in the first case.

    .. NOTE::

        this command seems to be partly superflous by now, because the residue
        of a valuation is already of type "function field" whenever this makes sense.
        However, even if `K` is a function field over a finite field, it is not
        guaranteed that the constant base field is a 'true' finite field, and then
        it is important to change that.

    """
    from mclf.curves.smooth_projective_curves import make_finite_field
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from sage.categories.function_fields import FunctionFields
    from sage.rings.function_field.function_field import is_FunctionField

    if is_FunctionField(K):
        k = K.constant_base_field()
        if k.is_finite() and hasattr(k, "base_field"):
            # k seems to be finite, but not a true finite field
            # we construct a true finite field k1 isomorphic to k
            # and F isomorphic to K with constant base field k1
            k1, phi, psi = make_finite_field(k)
            if hasattr(K, "polynomial"):
                # K is an extension of a rational function field
                K0 = K.rational_function_field()
                F0, phi0, psi0 = make_function_field(K0)
                f = K.polynomial().change_ring(phi0)
                F = F0.extension(f)
                return F, K.hom(F.gen(), phi0), F.hom(K.gen(), psi0)
            else:
                F = FunctionField(k1, K.variable_name())
                return F, K.hom(F.gen(), phi), F.hom(K.gen(), psi)
        else:
            return K, K.Hom(K).identity(), K.Hom(K).identity()

    if hasattr(K, "modulus") or hasattr(K, "polynomial"):
        # we hope that K is a simple finite extension of a field which is
        # isomorphic to a rational function field
        K_base = K.base_field()
        F_base, phi_base, psi_base = make_function_field(K_base)
        if hasattr(K, "modulus"):
            G = K.modulus()
        else:
            G = K.polynomial()
        R = G.parent()
        R_new = PolynomialRing(F_base, R.variable_name())
        G_new = R_new([phi_base(c) for c in G.list()])
        assert G_new.is_irreducible(), "G must be irreducible!"
        # F = F_base.extension(G_new, R.variable_name())
        F = F_base.extension(G_new, 'y')
        # phi0 = R.hom(F.gen(), F)
        # to construct phi:K=K_0[x]/(G) --> F=F_0[y]/(G),
        # we first 'map' from K to K_0[x]
        phi = K.hom(R.gen(), R, check=False)
        # then from K_0[x] to F_0[y]
        psi = R.hom(phi_base, R_new)
        # then from F_0[y] to F = F_0[y]/(G)
        phi = phi.post_compose(psi.post_compose(R_new.hom(F.gen(), F)))
        psi = F.hom(K.gen(), psi_base)
        return F, phi, psi
    else:
        # we hope that K is isomorphic to a rational function field over a
        # finite field
        if K in FunctionFields():
            # K is already a function field
            k = K.constant_base_field()
            k_new, phi_base, psi_base = make_finite_field(k)
            F = FunctionField(k_new, K.variable_name())
            phi = K.hom(F.gen(), phi_base)
            psi = F.hom(K.gen(), psi_base)
            return F, phi, psi
        elif hasattr(K, "function_field"):
            F1 = K.function_field()
            phi1 = F1.coerce_map_from(K)
            psi1 = F1.hom(K.gen())
            F, phi2, psi2 = make_function_field(F1)
            phi = phi1.post_compose(phi2)
            psi = psi2.post_compose(psi1)
            return F, phi, psi
        else:
            raise NotImplementedError