Function Fields

An integral curve C has a coordinate ring that is an integral domain. The function field of the curve is the corresponding field of fractions in the affine case and the homogeneous degree 0 part of this in projective cases. The function field of an affine curve is isomorphic to that of its projective closure. As with schemes generally, a function field is attached to projective curves and the same object represents the function field of all of its affine patchs.

Furthermore, in the curve case, there is a unique (up to abstract scheme isomorphism) (ordinary) projective non-singular curve tilde(C) which is birationally equivalent to C (ie there are maps from C to tilde(C) which are defined at all but finitely many points and whose composite is the identity where defined) <=> tilde(C) has the same function field (up to isomorphism) as C.

When C is projective, tilde(C) is just the normalisation of C. The normalisation tilde(C) differs from C only at singular points of the latter and C can be thought of as a singular model of tilde(C) and, as is usual with curves, most of the functionality provided by the function field and the objects attached - places, divisors etc. - can be more properly thought of as relating to tilde(C). The first section below treats function fields and some basic functions related to them and their elements.

From now on we assume that the reader is familiar with the notion of divisor, linear equivalence and their relationship with function fields. If not, there are very brief discussions of them at the beginning of each section and also in the introduction to this chapter, but you may also consult standard texts such as [Har77] Chapter II, 6 (especially from page 136) and Chapter IV for a more serious treatment.

For functions working with elements of a function field of a scheme and the scheme itself see Section Function Fields and their Elements.

Contents

Function Fields

For the purposes of this section, function fields are fields of rational functions on a curve C. Let f be an element and p a nonsingular rational point of C. Then one can evaluate f at p and compute the order of a zero or a pole of f at p, an integer which is positive for zeros and negative for poles. This allows points of the curve to be considered as valuations of the function field.

In fact, the proper language for discussing valuations and function fields is that of places and divisors, which really correspond to points of the projective normalisation tilde(C) of C and formal sums of these, and they are discussed in later sections. Functions in this section which take a point of a curve as an argument are convenient shorthands for functions taking a place and are only allowed when there is no ambiguity about which place is intended, which is why p is required to be non-singular. Functions which compute the zeros and poles of rational functions properly return divisors, so will be discussed later.

Finally, function fields and divisor groups are cached so that recomputation is avoided. Although it is transparent in practice, it is worth remembering that the function fields and divisor groups are always attached to the projective model of a curve, rather than to any of the affine models. Since these are all tightly related, it doesn't make any difference. The support points of divisors will be returned as points on the projective model since they can quite easily lie at infinity on any particular affine model. For a completely clean treatment, it is possible to work exclusively with the projective model, although it is certainly not necessary. Indeed, for some time the elliptic curve machinery in Magma has happily presented affine models of curves together with projective points.

HasFunctionField(C) : Crv -> BoolElt
FunctionField(C) : Crv -> FldFunFracSch
The function field of the curve C, a field isomorphic to the field of fractions of the coordinate ring of C. It can be assigned generator names using the diamond bracket notation, as in the example below. The function field will only exist when C is integral (reduced and irreducible) and this can be checked directly or by calling the function below if it is in doubt.
Curve(F) : FldFunFracSch -> Crv
The curve used to create the function field F, or the projective closure of that curve (if it was affine). The function field is stored on projective curves so that the same field is returned whenever it is called for from any patch of the projective curve.
F ! r : FldFunFracSch, RngElt -> FldFunFracSchElt
Coerce the ring element r into the function field F of a scheme. For the coercion to be successful r must be in a ring related to the scheme of F, e.g. the base ring or coordinate ring of (or a field of fractions of) the scheme or one of its affine patches or a subscheme or super scheme.
ProjectiveFunction(f) : FldFunFracSchElt -> RngFunFracElt
Return the function f in the function field of a scheme as a function in projective coordinates (as an element in the field of fractions of the coordinate ring of the projective scheme having function field the parent of f).

Example Crv_ff-creation-example (H121E24)

After creating a curve in the usual way we make its function field F.
> P<x,y,z> := ProjectiveSpace(Rationals(),2);
> C := Curve(P,x^4 + 2*x*y^2*z + 5*y*z^3);
> F<a,b> := FunctionField(C);
> F;
Function Field of Curve over Rational Field defined by
x^4 + 2*x*y^2*z + 5*y*z^3
> Curve(F);
Curve over Rational Field defined by
x^4 + 2*x*y^2*z + 5*y*z^3
> b^2;
b^2;
Once constructed, the function field will be stored with the curve (or its projective closure). Thus the same field will be returned from multiple function calls.
> FunctionField(C) eq FunctionField(AffinePatch(C,3));
true
p @ f : Pt, FldFunFracSchElt -> RngElt
f(p) : Pt, FldFunFracSchElt -> RngElt
Evaluate(f, p) : RngElt, Pt -> RngElt
The ring element f(p) where f is an element of the function field of the curve on which p is a point. If f has a pole at p the value infinity is returned.
Expand(f, p) : FldFunFracSchElt[Crv], PlcCrvElt -> RngSerElt, FldFunFracSchElt
Given an element f on a curve C and a place p of C return a series which is the expansion of f at p and the uniformizing element of p.
Completion(F, p) : FldFunFracSch[Crv], PlcCrvElt -> RngSer, Map
    Precision: RngIntElt                Default: 20
The completion of the function field F of the curve C at the place p of C and a map from F into its completion.
Degree(f) : FldFunFracSchElt[Crv] -> RngIntElt
Given an element f of the function field of a curve, return the degree of f. This is the degree of the map given by f to (P)1 or the degree of the numerator and denominator of the principal divisor of f. If f is constant, then 0 is returned.
Valuation(f, p) : RngElt, Pt -> RngIntElt
The degree of the zero of the function f at the point p where f is a function on the curve on which p is a point. A negative value indicates there is a pole of f at p.
Valuation(p) : Pt -> Map
The valuation of the function field of the curve on which p lies centred at the point p. This is a map from the function field to the integers.
UniformizingParameter(p) : Pt -> FldFunFracSchElt
A rational function on the curve of the nonsingular point p which having valuation 1 at p.
Module(S) : [FldFunFracSchElt[Crv]] -> Mod, Map, [ModElt]
    Preimages: BoolElt                  Default: false
    IsBasis: BoolElt                    Default: false
Given a sequence S of elements of a function field of a curve C return the module over the base ring of C generated by the elements of S. Also return the map from the module to the function field and a sequence of preimages of the elements of S if Preimages is true.

If IsBasis is true then the elements of S will be assumed to be a basis of the module.

Relations(S) : [FldFunFracSchElt[Crv]] -> ModTupRng
Relations(S, m) : [FldFunFracSchElt[Crv]], RngIntElt -> ModTupRng
Given a sequence S of elements of a function field of a curve C return the module over the base ring R of C of R-linear relations between the elements of S.
Genus(C) : Crv -> RngIntElt
The genus of the curve C.
FieldOfGeometricIrreducibility(C) : Crv -> Rng, Map
Return the algebraic closure of the base ring of C in the function field of C along with the map including the closure in the function field.
IsAbsolutelyIrreducible(C) : Crv -> BoolElt
Returns true if the field of geometric irreducibility of the curve C is the base ring of C.
DimensionOfFieldOfGeometricIrreducibility(C): Crv -> RngIntElt
The dimension of the field of geometric irreducibility of the curve C over the base ring of C.

Example Crv_ff-elements-example (H121E25)

Having made a curve and its function field we make an element of the function field using its named generators a, b. The function is put into a convenient form which, for this F, ensures that the denominator is a polynomial in a alone.
> P<x,y,z> := ProjectiveSpace(Rationals(),2);
> C := Curve(P,x^4 + 2*x*y^2*z + 5*y*z^3);
> F<a,b> := FunctionField(C);
> f := a/b;
> f;
(-2*a*b - 5)/a^3
Now we choose a point of the curve and find that f has a pole there of order 3.
> p := C ! [0,0,1];
> Evaluate(f,p);
Infinity
> Valuation(f,p);
-3
Computing the valuations of the generators we notice that a is a uniformising parameter at p --- indeed, it is the parameter automatically returned. Clearly the valuation of f=a/b at p should be 1 - 4= - 3 as computed in the previous line.
> vp := Valuation(p);
> vp(a), vp(b);
1 4
> UniformizingParameter(p);
a
GapNumbers(C) : Crv -> [RngIntElt]
The gap numbers of the curve C.
WronskianOrders(C) : Crv -> [RngIntElt]
The Wronskian orders of the curve C.
NumberOfPlacesOfDegreeOverExactConstantField(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
NumberOfPlacesDegECF(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
The number of places of degree m of the curve C defined over a finite field. Contrary to the Degree function the degree is here taken over the field of geometric irreducibility.
NumberOfPlacesOfDegreeOneOverExactConstantField(C) : Crv[FldFin] -> RngIntElt
NumberOfPlacesOfDegreeOneECF(C) : Crv[FldFin] -> RngIntElt
The number of places of degree one of the curve C defined over a finite field. Contrary to the Degree() function the degree is here taken over the field of geometric irreducibility.
NumberOfPlacesOfDegreeOneOverExactConstantField(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
NumberOfPlacesOfDegreeOneECF(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
The number of places of degree one in the constant field extension of degree m of the curve C. Contrary to the Degree() function the degree is here taken over the field of geometric irreducibility.
NumberOfPlacesOfDegreeOneECFBound(C) : Crv -> RngIntElt
NumberOfPlacesOfDegreeOneOverExactConstantFieldBound(C) : Crv[FldFin] -> RngIntElt
NumberOfPlacesOfDegreeOneECFBound(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
NumberOfPlacesOfDegreeOneOverExactConstantFieldBound(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
An upper bound on the number of places of degree one in the constant field extension of degree m (if given) of the curve C. Contrary to the Degree function the degree is here taken over the respective exact constant fields.
DivisorOfDegreeOne(C) : Crv[FldFin] -> DivCrvElt
Return a divisor of the curve C of degree 1 over its field of geometric irreducibility.
SerreBound(C) : Crv[FldFin] -> RngIntElt
SerreBound(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
IharaBound(C) : Crv[FldFin] -> RngIntElt
IharaBound(C, m) : Crv[FldFin], RngIntElt -> RngIntElt
The Serre and Ihara bounds of the number of places of degree 1 over the field of geometric irreducibility of the curve C over the extension of degree m of the base ring of C, which must be a finite field.

Zeta Functions of Curves

The zeta function of a curve C over a finite field k is a generating function encoding #C(l) for all finite field extensions l/k. Determining the zeta function is equivalent to determining #C(ki) for the field extensions ki/k of degree 1 ≤i ≤g, where g is the genus of C.

The algorithms available in magma fall into three categories:

i)
naive enumeration methods
ii)
methods implemented specifically for genus 1 -- see Chapter ELLIPTIC CURVES
iii)
p-adic cohomology methods, which generalize Kedlaya's algorithm.

The last category includes the following:

i)
Harrison's extension of Kedlaya's algorithm for all hyperelliptic curves ([Har12]), and Vercauteren's implementation for characteristic 2
ii)
Mestre's canonical lift method as adapted by Lercier and Lubicz, for characteristic 2
iii)
(since V2.23) Minzlaff's implementation for superelliptic curves ([Min13]) which implements Harvey's O(Sqrt(p)) complexity improvement
iv)
(since V2.23) Tuitman's algorithm for general curves ([Tui16] and [Tui17]).

While Tuitman's algorithm is by far the most general, it requires as input a "good" lift to characteristic zero of the curve. For genus less than or equal to 5, such a model is given by GonalityPreservingLift, and this is done automatically by ZetaFunction(C). For higher genus, there is no general algorithm; however, for many curves it is trivial to find a good lift in practice. (For nondegenerate curves, an arbitrary lift to characteristic 0 will usually work. Any plane model of a curve over the rationals is a good lift for all but a finite number of primes.) In this case, Tuitman's algorithm may be invoked directly with ZetaFunction(f, p) where f defines the good lift -- details below.

LPolynomial(C) : Crv[FldFin] -> RngUPolElt
LPolynomial(C, m) : Crv[FldFin], RngIntElt -> RngUPolElt
ZetaFunction(C) : Crv[FldFin] -> FldFunRatUElt
ZetaFunction(C, m) : Crv[FldFin], RngIntElt -> FldFunRatUElt
    Al: MonStgElt                       Default: "Default"
    SetVerbose("ZetaFunction", n):      Maximum: 
The L-polynomial or ζ function of the projective normalisation of the curve C over the extension of degree m of the base ring of C, which must be a finite field.

By default, the algorithm is chosen automatically from the methods described above. The user may specify the algorithm by setting the optional argument Al to "Naive", "Harrison", "Minzlaff" or "Tuitman". (If the specified algorithm is not applicable, then the default algorithm may be used instead, or a runtime error may be thrown.)

Tuitman's Algorithm

The input to Tuitman's algorithm is a "good" lift of the desired curve to characteristic zero. The precise condition required is Assumption 1 in [Tui17]. Basically, a good lift is a plane model whose reduction is birational to the given curve, and for which the `x' coordinate map has branch and ramification locus which are smooth divisors over the ring of p-adic integers.

GonalityPreservingLift(C) : Crv[FldFun] -> RngUPolElt, AlgMatElt, AlgMatElt
For a non-hyperelliptic curve of genus 3,4 or 5 over a finite field, this returns a good lift in the sense above. In particular, the lift has the same gonality as the given curve. The function returns a polynomial f defining the lift, over the rationals or a number field. It also returns matrices W0, Winf that can be passed as optional arguments to ZetaFunction(f, p) below, in order to save recomputing them.

The algorithms are described in [CT17]. The method involves randomized search. If it fails to find a lift (after a large number of trials) an error results. In such cases, it is highly probable that no lift exists, which happens for some curves over small fields.

ZetaFunction(f, p) : RngUPolElt, RngIntElt -> FldFunRatUElt
    W0: AlgMatElt                       Default: 
    Winf: AlgMatElt                     Default: 
    exactcoho: BoolElt                  Default: false
    N: RngIntElt                        Default: 
    SetVerbose("Tuitman", n):           Maximum: 
This directly invokes Tuitman's algorithm. The polynomial f, together with optional arguments W0, Winf, specify a curve over a field K which is either Q or a number field. The prime integer p must be inert in K, and the function returns the zeta function of the curve over the residue field ZK/(p ZK). Note f is given as a (univariate) polynomial in K[x][y] that is monic in y.

The optional arguments W0, Winf are matrices over K(x) that define integral bases for the function field of the curve defined by f over K[x] and K[1/x], respectively. The other two options give some control over the internals. If a positive value is given for N, then calculations will be done with p-adic precision at most N -- this may get the correct answer faster. If exactcoho is set to true, then cohomology is computed using exact linear algebra over K instead of p-adic linear algebra -- this may be used as a check.

Zeta Function of a Singular Curve
ZetaFunctionOfCurveModel(C) : Crv[FldFin] -> FldFunRatUElt
    Zfn: FldFunRatUElt                  Default: 
Returns the ζ function of the actual curve model C rather than that of its projective normalisation tilde(C). C must still be a reduced and irreducible curve and defined over a finite field (F)q but it may be affine or singular.

The ζ function of C is defined by the usual formula in terms of the numbers #C((F)qn) (see Appendix C of [Har77]) and is still a rational function, even if C is affine and/or singular. From the definition, it is easy to see that the ζ function of C differs from that of tilde(C) as follows. We multiply by 1 - td to remove the contribution of a degree d place at infinity or lying over singular points of C and divide by 1 - td to put back in the contribution of a Galois-conjugate set of singular points defined over (F)qd.

The computation is performed in the obvious way, computing the places at infinity (in the affine case) and those over the singular locus using the standard function field machinery. The major work is in the initial computation of the ζ function of tilde(C), where ZetaFunction is called. If this ζ function is already known, it can be input via the parameter Zfn.

Example Crv_crv-zfn-crv-mod (H121E26)

A simple example is where C is the usual affine Weierstrass model of an elliptic curve E. The curve C is non-singular and only differs from E by the removal of the single k-rational point O at infinity. The ζ function of C is therefore the usual ζ function of E multiplied by 1 - t.
> k := GF(7);
> E := EllipticCurve([k|0,5]);
> ze1 := ZetaFunction(E);
> ze1;
(7*$.1^2 - $.1 + 1)/(7*$.1^2 - 8*$.1 + 1)
> A<x,y> := AffineSpace(k,2);
> C := Curve(A,y^2-x^3-5);
> ze2 := ZetaFunctionOfCurveModel(C);
> ze2;
(-7*$.1^2 + $.1 - 1)/(7*$.1 - 1)
> ze2/ze1;
-$.1 + 1

Representations of the Function Field

The function field of a scheme has very little direct functionality. But when the scheme is a curve the function field is isomorphic to an algebraic function field as described in Chapter ALGEBRAIC FUNCTION FIELDS. This isomorphism is used internally in many computations for curves. Although the isomorphic algebraic function field can be retrieved from the function field of the scheme, this should not be necessary during ordinary usage of the curves.

AlgorithmicFunctionField(F) : FldFunFracSch -> FldFun, Map
Given the function field F of a curve C, this function returns the background algebraic function field, AF. As this is the object where such calculations as those involving places, divisors and differentials are performed, we refer to it as the algorithmic or arithmetic function field. Since there are curve functions which provide an interface to most of the functionality of this field via C, F and its elements, the user can usually avoid accessing AF directly. However, when it is required, it is also usually necessary to translate between elements of F and AF. A map from F to AF is thus also returned. This map is invertible and its inverse is used to map elements the other way.
FunctionFieldPlace(p) : PlcCrvElt -> PlcFunElt
CurvePlace(C, p) : Crv, PlcFunElt -> PlcCrvElt
FunctionFieldDivisor(d) : DivCrvElt -> DivFunElt
CurveDivisor(C, d) : Crv, DivFunElt -> DivCrvElt
FunctionFieldDifferential(d) : DiffCrvElt -> DiffFunElt
CurveDifferential(C, d) : Crv, DiffFunElt -> DiffCrvElt
Return the place, divisor or differential of the algebraic function field corresponding to the place, divisor or differential of a curve or convert the place p, divisor or differential d of an algebraic function field into a place, divisor or differential of the curve C.

Differentials

The space of differentials in Magma is the vector space of elements df over the function field of a curve, where f is any element of the function field and where the operator d satisfies the usual derivation conditions. This vector space is called the differential space and corresponds to the Kähler differentials of [Har77], II.8. Note that the differential space is not explicitly a vector space in Magma. Rather, as so often when there are many different structures to be considered, a vector space together with a map to the space of differentials is given. (Of course, basic vector space arithmetic works on the space of differentials.) In fact, this is appropriate: after all, Kähler differentials are merely a model of an object which one might prefer to define by its universal properties.

Creation of Differentials
DifferentialSpace(C) : Crv -> DiffCrv
The space of differentials of the curve C.
SpaceOfDifferentialsFirstKind(C) : Crv -> ModFld, Map
SpaceOfHolomorphicDifferentials(C) : Crv -> ModFld, Map
Given a curve C, this function returns a vector space V and a map from V to the space of differentials of C with image the holomorphic differentials on C.
BasisOfDifferentialsFirstKind(C) : Crv -> [DiffCrvElt]
BasisOfHolomorphicDifferentials(C) : Crv -> [DiffCrvElt]
Given a curve C, this function returns a basis for the space of holomorphic differentials of C.
DifferentialSpace(D) : DivCrvElt -> ModFld,Map
Given a divisor D associated with curve C, this function returns a vector space V and a map from V to the space of differentials of the curve C containing the divisor D with image the differentials of ωC(D). Colloquially, this refers to the differentials whose zeros are at least the positive (or effective) part of D and whose poles are no worse than the negative part of D.
DifferentialBasis(D) : DivCrvElt -> [DiffCrvElt]
Given a divisor D on a curve, this function returns the basis of the differential space of D.
Differential(a) : FldFunFracSchElt -> DiffCrvElt
The exact differential d(a) of the function field element a.
Operations on Differentials

The space of differentials admits vector space operations over the function field of the curve. As such, it is one-dimensional so one can even divide two non-zero differentials to recover an element of the function field.

f * x : RngElt,DiffCrvElt -> DiffCrvElt
x * f : DiffCrvElt,RngElt -> DiffCrvElt
x + y : DiffCrvElt,DiffCrvElt -> DiffCrvElt
- x : DiffCrvElt -> DiffCrvElt
x - y : DiffCrvElt,DiffCrvElt -> DiffCrvElt
x / r : DiffCrvElt,RngElt -> DiffCrvElt
x / y : DiffCrvElt,DiffCrvElt -> FldFunFracSchElt

The basic arithmetic in the space of differentials. Thought of as a vector space over the function field, this space is one-dimensional. The final operation uses this fact to return a function field element as the quotient of two differentials.

Identity(S) : DiffCrv -> DiffCrvElt
The identity differential of the differential space S of a curve.
Curve(S) : DiffCrv -> Crv
The curve for which S is the space of differentials.
Curve(a) : DiffCrvElt -> Crv
The curve to which the differential a belongs.
S eq T : DiffCrv,DiffCrv -> BoolElt
Returns true if and only if the two spaces of differentials S and T are the same.
a eq b : DiffCrvElt,DiffCrvElt -> BoolElt
Returns true if and only if the differentials a and b are equal.
a in S : Any,DiffCrv -> BoolElt
Returns true if and only if a is an element of the differential space S of a curve.
IsExact(a) : DiffCrvElt -> BoolElt
Returns true if and only if a is known to be an exact differential, that is, if it is known to be of the form df. If this is not already known, no further attempt is made to determine that.
IsZero(a) : DiffCrvElt -> BoolElt
Returns true if and only if the differential a is the zero differential.
Valuation(d, P) : DiffCrvElt, PlcCrvElt -> RngIntElt
The valuation of the differential d of a curve at the place P of the same curve.
Residue(d, P): DiffCrvElt, PlcCrvElt -> RngElt
The residue of the differential d of a curve at the place P of the same curve.
Divisor(d) : DiffCrvElt -> DivCrvElt
The divisor (f) + (dx) of the differential d = f dx of a curve.
Module(L) : [DiffCrvElt] -> Mod, Map, [ ModElt ]
    IsBasis: BoolElt                    Default: false
    PreImages: BoolElt                  Default: false
Given a sequence L of differentials of a curve C, return the module over the base ring of C generated by the differentials in L as an abstract module and a map from the module into the space of differentials of C.

If the parameter IsBasis is set to true then the elements in L are assumed to be a basis for the module returned. If PreImages is set to true then a sequence of the preimages of the basis elements is also returned.

Relations(L) : [DiffCrvElt] -> ModTupFld
Relations(L, m) : [DiffCrvElt], RngIntElt -> ModTupFld
Given a sequence L of differentials of a curve C, return the module over the base ring R of C of R-linear relations between the elements of L. If given, the argument m is used to compute a generating system for the relation module such that the corresponding generating system of { ∑i=1m vi ai | v = (vi)i ∈V } consists of "small" elements where ai are the elements of L.
Cartier(a) : DiffCrvElt -> DiffCrvElt
Cartier(a, r) : DiffCrvElt,RngIntElt -> DiffCrvElt
Given a differential a belonging to a curve C and a positive integer r, this function returns the result of applying the Cartier divisor to a r times (or just once if the argument r is omitted). More precisely, let C be a curve over the perfect field k with function field F, x ∈F be a separating variable and a = g dx ∈Ω(C) with g ∈F be a differential. The Cartier operator is defined by CA(a) = ( - dp - 1 g / dxp - 1 )1/p dx. This function computes the r-th iterated application of CA to a.
CartierRepresentation(C) : Crv -> AlgMatElt, SeqEnum[DiffCrvElt]
CartierRepresentation(C, r) : Crv, RngIntElt -> AlgMatElt, SeqEnum[DiffCrvElt]
Given a curve C and a positive integer r, this function determines a row representation matrix for action of the Cartier operator on a basis of the space of holomorphic differentials of C, (applied r times). More precisely, let C be a curve over the perfect field k, ω1, ..., ωg ∈Ω(C) be a basis for the holomorphic differentials and r ∈Z≥1. Let M = (λi, j)i, j ∈kg x g be the matrix such that CAri) = ∑m=1g λi, m ωm for all 1 ≤i ≤g. This function returns M and (ω1, ..., ωg).

Example Crv_curve-differentials (H121E27)

In this example we create a curve known to have genus 3 (a nonsingular plane quartic). So it should have a three-dimensional space of holomorphic differentials.

> P<x,y,z> := ProjectiveSpace(Rationals(),2);
> C := Curve(P,x^4+y^4+z^4);
> Omega_C,phi := SpaceOfHolomorphicDifferentials(C);
> Omega_C;
KModule of dimension 3 over Rational Field
> F<a,b> := FunctionField(C);
> phi;
Mapping from: ModFld: Omega_C to Space of differentials of F
That is good. Now we make a differential and check whether it is exact (which it obviously is since that's how we made it).
> f := a/b;
> df := Differential(f);
> df;
(-a/(b^6 + b^2)) d(b)
> Curve(df) eq C;
true
> IsExact(df);
true
V2.28, 13 July 2023