# Exact $p$-Adic Rings

## Introduction

The exact $p$-adic rings and fields use representations which contain a kind and a list of dependencies. These rings and their elements can then be approximated to as much precision as the objects they depend on allow, some to arbitrary precision depending on their construction. Approximations are calculated to some epoch $n$ which is equivalent to precision $2^n$. Such representations are often referred to as “lazy” as the work of computing to precision is delayed until it is necessary. The exact $p$-adic rings and fields use the inexact $p$-adic rings and fields described in the majority of this chapter for approximations.

For example, an element of an exact $p$-adic ring resulting from the addition of 2 elements will store that it is the sum of these two elements and approximations to this sum are computed by adding the corresponding approximations of the summands, when such approximations are required.

An advantage of this lazy representation is that a precision does not have be decided before computations are started. A disadvantage of this exact representation occurs when approximations are required to incredibly high precision, some precisions which may be considerably time and space expensive.

Exact $p$-adic rings have type `RngXPad`, exact $p$-adic fields `FldXPad`, their elements `RngXPadElt` and `FldXPadElt` respectively. There is also a dedicated polynomial ring type `RngUPolXPad` whose elements have type `RngUPolXPadElt`.

For further information see [[Doris, 2021](../../references.md#cite-doris-2021)].

### `IsExactpAdic(x): Any -> BoolElt`

Returns `true` if $x$ is an exact $p$-adic object, such as a ring, field, element, or polynomial.

## Exact $p$-adic Rings and Fields

In this section we describe the construction and functionality of the exact $p$-adic rings and fields.

### Construction of Exact $p$-adic Rings and Fields

#### `pAdicField(p : parameters): RngIntElt -> FldXPad`

```magma
Exact : BoolElt                    Default: false
Global: BoolElt                    Default: true
```

Returns ${\mathbb{Q}}_p$ as an exact $p$-adic field if `Exact` is set to `true` otherwise returns an inexact $p$-adic field. If `Global` is set to `false` then a new object is constructed rather than reusing an existing object.

#### `pAdicRing(p : parameters): RngIntElt -> FldXPad`

```magma
Exact : BoolElt                    Default: false
Global: BoolElt                    Default: true
```

Returns ${\mathbb{Z}}_p$ as an exact $p$-adic integer ring if `Exact` is set to `true` otherwise returns an inexact $p$-adic field. If `Global` is set to `false` then a new object is constructed rather than reusing an identical existing object.

#### `ext<K | f>: FldXPad, RngUPolElt -> RngXPad`

#### `ext<K | f>: FldXPad, RngUPolXPadElt -> RngXPad`

#### `ext<K | f>: FldXPad, [RngXPadElt] -> RngXPad`

#### `ext<K | d>: FldXPad, RngIntElt -> RngXPad`

#### `ext<K | f>: RngXPad, RngUPolElt -> RngXPad`

#### `ext<K | f>: RngXPad, RngUPolXPadElt -> RngXPad`

#### `ext<K | f>: RngXPad, [RngXPadElt] -> RngXPad`

#### `ext<K | d>: RngXPad, RngIntElt -> RngXPad`

Construct the extension defined by the polynomial $f$, which must be inertial or Eisenstein, or an unramified extension of degree $d$.

#### `Example: Constr Ex (ex-72b734)`

The construction of an exact $p$-adic field is shown as well as extensions, both unramified and ramified.

```magma
> Qp := pAdicField(11 : Exact);
> U := ext<Qp | 3>;
> U;
Unramified extension of degree 3 of 11-adic field (exact)
> R := ext<U | Polynomial([11, 11^2, 1])>;
> R;
Totally ramified extension of degree 2 of Unramified extension of degree 3 of
11-adic field (exact)
> ext<Qp | Polynomial([3, 5, 1])>;
Unramified extension of degree 2 of 11-adic field (exact)
> ext<Qp | Polynomial([11, 2*11^2, 1])>;
Totally ramified extension of degree 2 of 11-adic field (exact)

```

### Related Structures

#### `RingOfIntegers(L): FldXPad -> RngXPad`

#### `RingOfIntegers(L): RngXPad -> RngXPad`

#### `IntegerRing(L): FldXPad -> RngXPad`

#### `Integers(L): FldXPad -> RngXPad`

#### `IntegerRing(L): RngXPad -> RngXPad`

#### `Integers(L): RngXPad -> RngXPad`

The ring of integers of the exact $p$-adic field $L$.

#### `FieldOfFractions(L): FldXPad -> FldXPad`

#### `FieldOfFractions(L): RngXPad -> FldXPad`

The field of fractions of the exact $p$-adic ring $L$.

#### `BaseField(F): FldXPad -> FldXPad`

#### `CoefficientField(F): FldXPad -> FldXPad`

Returns the base field of the exact $p$-adic field $F$ when $F$ is an extension, or $F$ when $F$ is the prime field.

#### `BaseRing(R): RngXPad -> RngXPad`

#### `CoefficientRing(R): RngXPad -> RngXPad`

Returns the base ring of the exact $p$-adic ring $R$ when $R$ is an extension, or $R$ when $R$ is the prime ring.

#### `ResidueClassField(L): FldXPad -> FldFin, Map`

#### `ResidueClassField(L): RngXPad -> FldFin, Map`

The residue class field $F$ of the exact $p$-adic ring or field $K$, as a finite field, and the map from $K$ to $F$.

#### `pAdicQuotientRing(L, k): FldXPad, RngIntElt -> RngPadRes, Map`

#### `pAdicQuotientRing(L, k): RngXPad, RngIntElt -> RngPadRes, Map`

#### `quo<L | x>: RngXPad, Any -> RngPadRes, Map`

#### `quo<L | x>: FldXPad, Any -> RngPadRes, Map`

The quotient of the exact $p$-adic ring or field $L$ by $L!x$, or by $\pi^k$ where $\pi$ is the uniformizing element of $L$.

#### `InfinitePrecisionApproximation(K): FldXPad -> FldPad`

#### `InfinitePrecisionApproximation(K): RngXPad -> RngPad`

The $p$-adic field of type `FldPad` or the $p$-adic ring of type `RngPad` with `Precision` `Infinity()` compatible with all finite–precision approximations of the exact $p$-adic field or ring $K$.

#### `R eq T: RngXPad, RngXPad -> BoolElt`

#### `R eq T: FldXPad, FldXPad -> BoolElt`

Return whether the exact $p$-adic rings or fields $R$ and $T$ are equal.

#### `Example: Related Ex (ex-34e873)`

```magma
> Qp := pAdicField(5 : Exact);
> Zp := Integers(Qp);
> FieldOfFractions(Zp) eq Qp;
true
> L := ext<ext<Zp | 5> | Polynomial([5, 5^3, 5^2, 1])>;
> L;
Totally ramified extension of degree 3 of Unramified extension of degree 5 of
5-adic ring (exact)
> BaseRing(L);
Unramified extension of degree 5 of 5-adic ring (exact)
> ResidueClassField(L);
Finite field of size 5^5
Mapping from: RngXPad: L to GF(5^5)
> InfinitePrecisionApproximation(L);
Totally ramified extension defined by a map over Unramified extension defined by
a map over 5-adic ring
> pAdicQuotientRing(L, 20);
Quotient of Totally ramified extension of Unramified extension of Quotient of
the 5-adic ring modulo the ideal generated by 5^7 modulo x^5 + 4*x + 3 modulo
x^3 + 25*x^2 + 125*x + 5 and $.1^20
Mapping from: RngXPad: L to ChangePrecision(TotallyRamifiedExtension(
UnramifiedExtension(pAdicQuotientRing(5, 7), Polynomial(pAdicQuotientRing(5, 7),
\\[3, 4, 0, 0, 0, 1])), Polynomial([UnramifiedExtension(pAdicQuotientRing(5, 7),
Polynomial(pAdicQuotientRing(5, 7), \\[3, 4, 0, 0, 0, 1])) | [5], [125], [25],
[1]])), 20)

```

### Generating Elements

#### `R . i: FldXPad, RngIntElt -> FldXPadElt`

#### `R . i: RngXPad, RngIntElt -> RngXPadElt`

#### `Name(R, i): RngXPad, RngIntElt -> RngXPadElt`

#### `Name(R, i): FldXPad, RngIntElt -> FldXPadElt`

Given an exact $p$-adic ring or field $R$ and a positive integer $i$ return the $i$-th generator of $R$.

#### `AssignNames(~R, S): RngXPad, SeqEnum[MonStgElt]`

#### `AssignNames(~R, S): FldXPad, SeqEnum[MonStgElt]`

Given an exact $p$-adic ring or field $R$ assign the string in the sequence $S$ of length 1 to be the name used when printing elements of $R$. On construction of $R$, `R<x>` can be used to assign the string `"x"` as the name to be used when printing in which case the identifier `x` will be assigned the value of `R.1`.

#### `Generator(R): FldXPad -> FldXPadElt`

#### `Generator(R): RngXPad -> RngXPadElt`

Returns the generator of the exact $p$-adic ring or field $R$ over its base field. For extensions $R$, a root of its defining polynomial is returned, otherwise 1.

#### `UniformizingElement(R): FldXPad -> FldXPadElt`

#### `UniformizingElement(R): RngXPad -> RngXPadElt`

Returns an element of valuation 1 of the exact $p$-adic ring or field $R$.

#### `ResidueGenerator(R): FldXPad -> FldXPadElt`

#### `ResidueGenerator(R): RngXPad -> RngXPadElt`

Returns an element of valuation 0 whose residue class generates the residue class field of the exact $p$-adic ring or field $R$ over ${\mathbb{F}}_p$.

#### `AbsoluteGenerator(R): FldXPad -> FldXPadElt`

#### `AbsoluteGenerator(R): RngXPad -> RngXPadElt`

An element which generates the exact $p$-adic ring or field $R$ over its prime subfield. This will be either 1, a uniformizing element, a residue generator, or the sum of the two, depending on the inertia and ramification degrees.

#### `Example: Gen Ex (ex-1abc7d)`

```magma
> Zp := pAdicRing(7 : Exact);
> Zp.1;
1 + O(7^20)
> UniformizingElement(Zp);
7 + O(7^20)
> ResidueGenerator(Zp);
1 + O(7^20)
> L := ext<ext<Zp | Polynomial([7, 77, 7*17, 1])> | 4>;
> BL := BaseRing(L);
> L.1;
L.1 + O($.1^20)
> Generator(L);
L.1 + O($.1^20)
> UniformizingElement(L);
BL.1 + O(BL.1^20)
> ResidueGenerator(L);
L.1 + O($.1^20)
> AbsoluteGenerator(L);
L.1 + BL.1 + O(BL.1^20)

```

### Invariants

#### `Prime(L): FldXPad -> RngIntElt`

#### `Prime(L): RngXPad -> RngIntElt`

The (rational) prime $p$ having valuation equal to the ramification degree of the exact $p$-adic ring or field $L$.

#### `Degree(L, K): FldXPad, FldXPad -> RngIntElt`

#### `Degree(L): FldXPad -> RngIntElt`

#### `Degree(L): RngXPad -> RngIntElt`

#### `Degree(L, K): RngXPad, RngXPad -> RngIntElt`

The degree of the extension $L$ over the exact $p$-adic ring or field $K$ if given or the base ring of $L$ otherwise.

#### `InertiaDegree(L, K): FldXPad, FldXPad -> RngIntElt`

#### `InertiaDegree(L): FldXPad -> RngIntElt`

#### `InertiaDegree(L, K): RngXPad, RngXPad -> RngIntElt`

#### `InertiaDegree(L): RngXPad -> RngIntElt`

The inertia degree of the extension $L$ over the exact $p$-adic ring or field $K$ if given or the base ring of $L$ otherwise.

#### `RamificationDegree(L, K): FldXPad, FldXPad -> RngIntElt`

#### `RamificationDegree(L): FldXPad -> RngIntElt`

#### `RamificationIndex(L): FldXPad -> RngIntElt`

#### `RamificationIndex(L, K): FldXPad, FldXPad -> RngIntElt`

#### `RamificationDegree(L): RngXPad -> RngIntElt`

#### `RamificationDegree(L, K): RngXPad, RngXPad -> RngIntElt`

#### `RamificationIndex(L): RngXPad -> RngIntElt`

#### `RamificationIndex(L, K): RngXPad, RngXPad -> RngIntElt`

The ramification degree of the extension $L$ over the exact $p$-adic ring or field $K$ if given or the base ring of $L$ otherwise.

#### `DefiningPolynomial(R): RngXPad -> RngUPolElt`

#### `DefiningPolynomial(R): FldXPad -> RngUPolElt`

```magma
Exact: BoolElt                    Default: true
```

Given an exact $p$-adic ring or field $R$ returns the defining polynomial of $R$ with type `RngUPolElt`, unless `Exact` is set to `true`, in which case the polynomial is returned with type `RngUPolXPadElt`.

#### `AbsoluteDegree(F): FldXPad -> RngIntElt`

#### `AbsoluteInertiaDegree(L): FldXPad -> RngIntElt`

#### `AbsoluteInertiaIndex(L): FldXPad -> RngIntElt`

#### `AbsoluteRamificationDegree(L): FldXPad -> RngIntElt`

#### `AbsoluteRamificationIndex(L): FldXPad -> RngIntElt`

#### `AbsoluteDegree(F): RngXPad -> RngIntElt`

#### `AbsoluteInertiaDegree(L): RngXPad -> RngIntElt`

#### `AbsoluteInertiaIndex(L): RngXPad -> RngIntElt`

#### `AbsoluteRamificationDegree(L): RngXPad -> RngIntElt`

#### `AbsoluteRamificationIndex(L): RngXPad -> RngIntElt`

The degree, inertia degree or ramification degree of the exact $p$-adic ring or field $L$ over its prime subfield.

#### `DiscriminantValuation(L): FldXPad -> RngIntElt`

#### `DiscriminantValuation(L, K): FldXPad, FldXPad -> RngIntElt`

#### `DiscriminantValuation(L, K): RngXPad, RngXPad -> RngIntElt`

#### `DiscriminantValuation(L): RngXPad -> RngIntElt`

The valuation of the discriminant of the extension $L/K$ of exact $p$-adic rings or fields. This is computed as the height of the leftmost vertex of the ramification polygon (and so avoids actually computing the discriminant). If it is not specified $K$ defaults to the base ring of $L$.

#### `RamificationPolygon(L): FldXPad -> NwtnPgon`

#### `RamificationPolygon(L, K): FldXPad, FldXPad -> NwtnPgon`

#### `RamificationPolygon(L, K): RngXPad, RngXPad -> NwtnPgon`

#### `RamificationPolygon(L): RngXPad -> NwtnPgon`

#### `RamificationPolygon(f): RngUPolXPadElt[FldXPad] -> NwtnPgon`

#### `RamificationPolygon(f): RngUPolXPadElt[RngXPad] -> NwtnPgon`

Constructs the ramification polygon of the Eisenstein or inertial polynomial $f$ over an exact $p$-adic ring or field. The input can instead be an extension $L/K$, where $K$ defaults to the base ring of $L$ if it is not specified.

The locations and slopes of the vertices correspond to different subfields fixed by different ramification subgroups of the Galois group. For example a horizontal face corresponds to an unramified subfield, and a face of slope -1 corresponds to a tame subfield. This is represented as a Newton Polygon (type `NwtnPgon`).

#### `Example: Invar Ex (ex-5789a2)`

```magma
> Qp := pAdicField(17 : Exact);
> Prime(Qp);
17
> Degree(Qp);
1
> L := ext<ext<Qp | 7> | Polynomial([3*17, 4*17^2, 2*17, 1])>;
> Prime(L);
17
> Degree(L);
3
> Degree(L, Qp);
21
> Degree(L, BaseField(L));
3
> InertiaDegree(L);
1
> RamificationDegree(L);
3
> DefiningPolynomial(L);
(1 + O(17^20))*$.1^3 + (2*17 + O(17^21))*$.1^2 + (4*17^2 + O(17^22))*$.1 + 3*17
    + O(17^21)
> Parent($1);
Univariate Polynomial Ring over Unramified extension of degree 7 of 17-adic
field (exact)
> DefiningPolynomial(CoefficientField(L));
(1 + O(17^20))*$.1^7 + O(17^2048)*$.1^6 + O(17^2048)*$.1^5 + O(17^2048)*$.1^4 +
    O(17^2048)*$.1^3 + O(17^2048)*$.1^2 + (12 + O(17^20))*$.1 + 14 + O(17^20)
> DefiningPolynomial(L : Exact);
(1 + O(17^20))*$.1^3 + (2*17 + O(17^21))*$.1^2 + (4*17^2 + O(17^22))*$.1 + 3*17
    + O(17^21)
> Parent($1);
Univariate polynomial ring (exact) over Unramified extension of degree 7 of
17-adic field (exact)
> AbsoluteDegree(L);
21
> DiscriminantValuation(L);
2
> DiscriminantValuation(L, Qp);
2
> RamificationPolygon(L);
Newton Polygon with vertices {(1, 2), (3, 0)} and defining points {(1, 2), (2,
1), (3, 0)}

```

## Exact $p$-adic Elements

In this section we describe the construction and functionality related to elements of exact $p$-adic rings and fields.

### `GetExactpAdicsPrintPrecision() -> RngIntElt`

Returns the precision to which exact $p$-adic objects are printed by default.

### `SetExactpAdicsPrintPrecision(k): Infty`

### `SetExactpAdicsPrintPrecision(k): RngIntElt`

Set the precision to which exact $p$-adic objects are printed by default to the integer $k$ or $\infty$.

### `K ! x: FldXPad, Any -> FldXPadElt`

### `R ! x: RngXPad, Any -> RngXPadElt`

### `elt<K | x>: FldXPad, Any -> FldXPadElt`

### `elt<R | x>: RngXPad, Any -> RngXPadElt`

Elements of an exact $p$-adic ring or field may be coerced from:

- Integers or rationals

- Any base field

- The residue class field

- Any compatible finite-precision $p$-adic field, ring or quotient ring

In the latter two cases, the coerced element has its precision capped to the precision of $x$, so is not really “exact”. To select a full-precision lift, use `CoerceAndLift(K,x)`.

### `AbsolutePrecision(x): FldXPadElt -> RngIntElt`

### `AbsolutePrecision(x): RngXPadElt -> RngIntElt`

The precision of the exact $p$-adic element $x$ relative to valuation 0.

### `RelativePrecision(x): FldXPadElt -> RngIntElt`

### `RelativePrecision(x): RngXPadElt -> RngIntElt`

The precision of the exact $p$-adic element $x$ relative to its weak valuation. The relative precision is zero if and only if $x$ is weakly zero.

### `Valuation(x): FldXPadElt -> RngIntElt`

### `Valuation(x): RngXPadElt -> RngIntElt`

The valuation of the exact $p$-adic element $x$. Note that if $x$ is weakly zero, its epoch will be increased until it is no longer weakly zero, or until its weak valuation is infinite. If $x$ is actually zero, this could compute forever.

### `WeakValuation(x): RngXPadElt -> RngIntElt`

### `WeakValuation(x): FldXPadElt -> RngIntElt`

A lower bound on the valuation of the exact $p$-adic element $x$. It is equal to the true valuation unless $x$ is weakly zero.

### `ShiftValuation(x, n): FldXPadElt, RngIntElt -> FldXPadElt`

### `ShiftValuation(x, n): RngXPadElt, RngIntElt -> RngXPadElt`

Multiply the exact $p$-adic element $x$ by the $m$th power of the uniformizing element. This returns an element whose valuation is $m$ more than that of $x$.

### `ValuationEq(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationEq(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationEq(x, n): RngXPadElt, RngIntElt -> BoolElt`

### `ValuationEq(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationNe(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationNe(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationNe(x, n): RngXPadElt, RngIntElt -> BoolElt`

### `ValuationNe(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationGe(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationGe(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationGe(x, n): RngXPadElt, RngIntElt -> BoolElt`

### `ValuationGe(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationGt(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationGt(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationGt(x, n): RngXPadElt, RngIntElt -> BoolElt`

### `ValuationGt(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationLe(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationLe(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationLe(x, n): RngXPadElt, RngIntElt -> BoolElt`

### `ValuationLe(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationLt(x, n): FldXPadElt, RngIntElt -> BoolElt`

### `ValuationLt(x, n): FldXPadElt, Infty -> BoolElt`

### `ValuationLt(x, n): RngXPadElt, Infty -> BoolElt`

### `ValuationLt(x, n): RngXPadElt, RngIntElt -> BoolElt`

Compare the valuation of the exact $p$-adic element $x$ to $n$. These always terminate.

### `IsUnit(x): RngXPadElt -> BoolElt`

### `IsUnit(x): FldXPadElt -> BoolElt`

Return `true` if the exact $p$-adic element $x$ is a unit.

### `IsIntegral(x): RngXPadElt -> BoolElt`

### `IsIntegral(x): FldXPadElt -> BoolElt`

Returns `true` if the exact $p$-adic element $x$ is an integer.

### `IsWeaklyZero(x): StrAnyXPadElt -> BoolElt`

### `IsWeaklyEqual(x, y): StrAnyXPadElt, StrAnyXPadElt -> BoolElt`

Returns `true` if the exact $p$-adic element $x$, respectively $x-y$, is zero up to its current precision. If $x$, respectively $x-y$, is zero then it is weakly zero, but not necessarily the other way around.

### `IsDefinitelyZero(x): StrAnyXPadElt -> BoolElt`

### `IsDefinitelyEqual(x, y): StrAnyXPadElt, StrAnyXPadElt -> BoolElt`

Returns `true` if the exact $p$-adic element $x$ is definitely zero, respectively, $x$ and $y$ are identical or both definitely zero.

### `CoerceAndLift(S, x): StrAnyXPad, Any -> StrAnyXPadElt`

Coerce $x$ into the exact $p$-adic structure $S$, and ensure its precision is unbounded. If $x$ is a finite-precision object, then ordinary coercion `S!x` will have capped precision whereas `CoerceAndLift(S,x)` will “lift” this to have unbounded precision

### Arithmetic with Elements

#### `x * y: FldXPadElt, FldXPadElt -> FldXPadElt`

#### `x * y: RngXPadElt, RngXPadElt -> RngXPadElt`

#### `x + y: FldXPadElt, FldXPadElt -> FldXPadElt`

#### `x + y: RngXPadElt, RngXPadElt -> RngXPadElt`

#### `- y: FldXPadElt -> FldXPadElt`

#### `- y: RngXPadElt -> RngXPadElt`

#### `x - y: RngXPadElt, RngXPadElt -> RngXPadElt`

#### `x - y: FldXPadElt, FldXPadElt -> FldXPadElt`

#### `x ^ n: FldXPadElt, RngIntElt -> FldXPadElt`

#### `x ^ n: RngXPadElt, RngIntElt -> RngXPadElt`

#### `x / y: FldXPadElt, FldXPadElt -> FldXPadElt`

#### `x / y: RngXPadElt, RngXPadElt -> RngXPadElt`

#### `x div y: RngXPadElt, RngXPadElt -> RngXPadElt`

#### `Quotrem(x, y): RngXPadElt, RngXPadElt -> RngXPadElt, RngXPadElt`

#### `GCD(x, y): FldXPadElt, FldXPadElt -> FldXPadElt`

#### `Gcd(x, y): FldXPadElt, FldXPadElt -> FldXPadElt`

#### `GreatestCommonDivisor(x, y): FldXPadElt, FldXPadElt -> FldXPadElt`

#### `GCD(x, y): RngXPadElt, RngXPadElt -> RngXPadElt`

#### `Gcd(x, y): RngXPadElt, RngXPadElt -> RngXPadElt`

#### `GreatestCommonDivisor(x, y): RngXPadElt, RngXPadElt -> RngXPadElt`

Given exact $p$-adic elements $x$ and $y$ return their greatest common divisor.

#### `ExtendedGreatestCommonDivisor(x, y): FldXPadElt, FldXPadElt -> FldXPadElt, FldXPadElt, FldXPadElt`

#### `XGCD(x, y): FldXPadElt, FldXPadElt -> FldXPadElt, FldXPadElt, FldXPadElt`

#### `Xgcd(x, y): FldXPadElt, FldXPadElt -> FldXPadElt, FldXPadElt, FldXPadElt`

#### `ExtendedGreatestCommonDivisor(x, y): RngXPadElt, RngXPadElt -> RngXPadElt, RngXPadElt, RngXPadElt`

#### `XGCD(x, y): RngXPadElt, RngXPadElt -> RngXPadElt, RngXPadElt, RngXPadElt`

#### `Xgcd(x, y): RngXPadElt, RngXPadElt -> RngXPadElt, RngXPadElt, RngXPadElt`

Given exact $p$-adic elements $x$ and $y$ return their greatest common divisor $g$ as well as $a$ and $b$ such that $g = a x + b y$.

#### `Example: Elts Ex (ex-bdd87d)`

```magma
> Zp := pAdicRing(19 :  Exact);
> x := Zp!3948701;
> y := Zp!748873*19;
> x;
3948701 + O(19^20)
> y;
14228587 + O(19^20)
> FieldOfFractions(Zp)!x;
3948701 + O(19^20)
> FieldOfFractions(Zp)!y;
748873*19 + O(19^21)
> AbsolutePrecision(x);
32
> RelativePrecision(x);
32
> Valuation(x);
0
> WeakValuation(x);
0
> ShiftValuation(x, 5);
9777374597399 + O(19^20)
> ValuationGe($1, 5);
true
> IsUnit(x);
true
> IsIntegral(x);
true
> Valuation(y);
1
> x + y;
18177288 + O(19^20)
> x*y;
56184435715487 + O(19^20)
> Valuation(y^5);
5
> x/y;
-14678086202175978502286566*19^-1 + O(19^19)
> Quotrem(x, y);
O(19^20) 3948701 + O(19^20)
> Quotrem(y, x);
15372121930607214329737477 + O(19^20) O(19^20)
> Gcd(x, y);
3948701 + O(19^20)
> Xgcd(19*x, y);
75025319 + O(19^20) 1 + O(19^20) O(19^20)
> IsWeaklyZero(Zp!0);
true
> IsDefinitelyZero(Zp!0);
false
> IsDefinitelyZero(FieldOfFractions(Zp)!0);
true
> IsDefinitelyEqual(x, x);
true
> CoerceAndLift(Zp, 0);
O(19^20)
> IsWeaklyZero($1);
true
> IsDefinitelyZero($2);
false
> CoerceAndLift(FieldOfFractions(Zp), 0);
0
> IsDefinitelyZero($1);
true

```

## Polynomials over Exact $p$-adic Rings and Fields

While polynomial rings of type `RngUPol` and polynomials of type `RngUPolElt` can be constructed in the regular way over exact $p$-adic rings and fields there is also a specific type of polynomial rings which can be constructed over the exact $p$-adic rings and fields. These polynomial rings have type `RngUPolXPad` and their elements have type `RngUPolXPadElt`.

### Exact Polynomial Rings

In this section we describe the construction and functionality for polynomial rings of type `RngUPolXPad`.

#### `PolynomialRing(R : parameters): Rng -> RngUPol`

```magma
Global: BoolElt                    Default: true
Exact : BoolElt                    Default: false
```

A polynomial ring specifically to parent polynomials with exact $p$-adic coefficients exists to be able to implement new kinds of polynomials which are best implemented by giving approximations of the entire polynomial wholesale, instead of giving each coefficient individually. This ring is constructed when the `Exact` parameter is set to `true`, otherwise an ordinary polynomial ring over the exact $p$-adic ring or field $R$ is constructed.

#### `R eq T: RngUPolXPad, RngUPolXPad -> BoolElt`

Given polynomial rings $R$ and $T$ over exact $p$-adic rings or fields, return whether $R$ and $T$ are equal.

#### `BaseRing(R): RngUPolXPad -> Rng`

#### `CoefficientRing(R): RngUPolXPad -> Rng`

Returns the coefficient ring of the polynomial ring $R$ over an exact $p$-adic ring or field.

#### `R . i: RngUPolXPad, RngIntElt -> RngXPadElt`

#### `Name(R, i): RngUPolXPad, RngIntElt -> RngUPolXPadElt`

#### `Generator(R): RngUPolXPad -> RngUPolXPadElt`

Returns the polynomial variable of the polynomial ring $R$ over an exact $p$-adic ring of field.

#### `AssignNames(~R, S): RngUPolXPad, SeqEnum[MonStgElt]`

Given a polynomial ring over an exact $p$-adic ring or field $R$ assign the string in the sequence $S$ of length 1 to be the name used for the variable of $R$ when printing elements of $R$. On construction of $R$, `R<x>` can be used to assign the string `"x"` as the name to be used when printing in which case the identifier `x` will be assigned the value of `R.1`.

#### `Example: Poly Ring Ex (ex-b44a56)`

```magma
> Zp := pAdicRing(7 : Exact);
> PolynomialRing(Zp);
Univariate Polynomial Ring over 7-adic ring (exact)
> PolynomialRing(Zp : Exact);
Univariate polynomial ring (exact) over 7-adic ring (exact)

```

### Polynomials

In these next sections we describe the construction and functionality for polynomials of type `RngUPolXPadElt`.

#### `R ! f: RngUPolXPad, Any -> RngUPolXPadElt`

Polynomials with exact $p$-adic coefficients can be constructed from:

- Other polynomials, either exact or ordinary, over any exact p-adic ring.

- Sequences of coefficients coercible to the base ring.

- Anything coercible to the base ring. If you are coercing from finite-precision rings, `CoerceAndLift(R,f)` may be appropriate.

#### `BaseRing(f): RngUPolXPadElt -> Rng`

#### `CoefficientRing(f): RngUPolXPadElt -> Rng`

Returns the coefficient ring of the polynomial $f$ over an exact $p$-adic ring or field.

#### `CanChangeRing(f, R): RngUPolXPadElt, Rng -> BoolElt, RngUPolXPadElt`

#### `ChangeRing(f, R): RngUPolXPadElt, Rng -> RngUPolXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field and a ring $R$, return whether the coefficients of $f$ can be coerced into $R$ and the polynomial with those coefficients in $R$ if so.

#### `Degree(f): RngUPolXPadElt -> RngIntElt`

Given a polynomial $f$ returns the true degree of $f$. That is, the corresponding leading coefficient is known to be non-zero.

#### `WeakDegree(f): RngUPolXPadElt -> RngIntElt`

Given a polynomial $f$ over an exact $p$-adic ring or field, returns an upper bound on the degree of $f$. That is, the corresponding leading coefficient may be weakly zero.

#### `Coefficient(f, i): RngUPolXPadElt, RngIntElt -> RngElt`

#### `Coefficients(f): RngUPolXPadElt -> SeqEnum`

Given a polynomial $f$ return the $i$th coefficient and all coefficients of $f$ respectively.

#### `ExactPolynomial(f): RngUPolXPadElt -> RngUPolXPadElt`

#### `ExactPolynomial(f): RngUPolElt -> RngUPolXPadElt`

Given a polynomial $f$ of type `RngUPolElt` over an exact $p$-adic ring or field, convert $f$ into a polynomial of type `RngUPolXPadElt`.

#### `Evaluate(f, x): RngUPolXPadElt, Any -> RngAnyXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field and an element $x$ coercible into the coefficient ring of $f$ return the value of $f$ when the variable is replaced by $x$.

#### `Derivative(f, m): RngUPolXPadElt, RngIntElt -> RngUPolXPadElt`

#### `Derivative(f): RngUPolXPadElt -> RngUPolXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field and an integer $m$, return the $m$th derivative of $f$ or the first derivative if $m$ is not specified.

#### `Discriminant(f): RngUPolXPadElt -> RngAnyXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field, return the discriminant, the product of the differences between the roots of $f$.

#### `Resultant(f, g): RngUPolXPadElt, RngUPolXPadElt -> RngAnyXPadElt`

Given polynomials $f$ and $g$ over an exact $p$-adic ring or field, return their resultant.

#### `IsInertial(f): RngUPolXPadElt -> BoolElt`

#### `IsEisenstein(f): RngUPolXPadElt -> BoolElt`

Given a polynomial $f$ over an exact $p$-adic ring or field, return whether the polynomial is inertial or Eisenstein, respectively.

#### `IsWeaklyZero(f): StrAnyXPadElt -> BoolElt`

#### `IsWeaklyEqual(f, g): StrAnyXPadElt, StrAnyXPadElt -> BoolElt`

Returns `true` if the exact $p$-adic polynomial $f$, respectively $f-g$, is zero up to its current precision. If $f$, respectively $f-g$, is zero then it is weakly zero, but not necessarily the other way around.

#### `IsDefinitelyZero(f): StrAnyXPadElt -> BoolElt`

#### `IsDefinitelyEqual(f, g): StrAnyXPadElt, StrAnyXPadElt -> BoolElt`

Returns `true` if the exact $p$-adic polynomial $f$ is definitely zero, respectively, $f$ and $g$ are identical or both definitely zero.

#### `CoerceAndLift(S, x): StrAnyXPad, Any -> StrAnyXPadElt`

Coerce $x$ into the exact $p$-adic structure $S$, and ensure its precision is unbounded. If $x$ is a finite-precision object, then ordinary coercion `S!x` will have capped precision whereas `CoerceAndLift(S,x)` will “lift” this to have unbounded precision

### Arithmetic

#### `x * y: RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `- y: RngUPolXPadElt -> RngUPolXPadElt`

#### `x + y: RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `x - y: RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `x / c: RngUPolXPadElt, RngElt -> RngUPolXPadElt`

#### `x ^ n: RngUPolXPadElt, RngIntElt -> RngUPolXPadElt`

#### `Quotrem(x, y): RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `x div y: RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `x mod y: RngUPolXPadElt, RngUPolXPadElt -> RngUPolXPadElt`

#### `Example: Poly Ex (ex-88ff30)`

```magma
> Qp := pAdicField(11 : Exact);
> f := Polynomial(Qp, [3241, 245, 134, 1345, 125, 1542]);
> f;
(1542 + O(11^20))*$.1^5 + (125 + O(11^20))*$.1^4 + (1345 + O(11^20))*$.1^3 +
    (134 + O(11^20))*$.1^2 + (245 + O(11^20))*$.1 + 3241 + O(11^20)
> f := ExactPolynomial(f); f;
(1542 + O(11^20))*$.1^5 + (125 + O(11^20))*$.1^4 + (1345 + O(11^20))*$.1^3 +
    (134 + O(11^20))*$.1^2 + (245 + O(11^20))*$.1 + 3241 + O(11^20)
> BaseRing(f);
11-adic field (exact)
> CanChangeRing(f, Integers(Qp));
true (1542 + O(11^20))*$.1^5 + (125 + O(11^20))*$.1^4 + (1345 + O(11^20))*$.1^3
    + (134 + O(11^20))*$.1^2 + (245 + O(11^20))*$.1 + 3241 + O(11^20)
> Degree(f);
5
> WeakDegree(ExactPolynomial(f));
5
> Coefficient(f, 2);
134 + O(11^20)
> Evaluate(f, Qp.1);
6632 + O(11^20)
> Derivative(f, 2);
(30840 + O(11^20))*$.1^3 + (1500 + O(11^20))*$.1^2 + (8070 + O(11^20))*$.1 + 268
    + O(11^20)
> Discriminant(f);
-77083727534419762054 + O(11^20)
> Resultant(f, Derivative(f));
213641244987848541309 + O(11^20)
> IsInertial(f);
true
> IsEisenstein(f);
false
> IsWeaklyZero(PolynomialRing(Qp : Exact)!0);
true
> IsDefinitelyZero(PolynomialRing(Qp : Exact)!0);
true
> IsWeaklyZero(f-f);
true
> IsDefinitelyZero(f-f);
false
> IsDefinitelyEqual(f, f);
true

```

### Factorization and Roots

The functionality in this section is related to taking roots and computing factorizations of polynomials. For some of these intrinsics there are restrictions on the input polynomial regarding multiple factors. Since no finite precision $p$-adic algorithm can provbably identify equal roots multiple factors are not checked for and some intrinsics may run forever on input having multiple factors.

#### `NewtonPolygon(f): RngUPolXPadElt[RngXPad] -> NwtnPgon`

#### `NewtonPolygon(f): RngUPolXPadElt[FldXPad] -> NwtnPgon`

Returns the Newton polygon of the polynomial $f$ over an exact $p$-adic ring or field.

#### `Roots(f, R): RngUPolElt, FldXPad -> SeqEnum`

#### `Roots(f, R): RngUPolElt, RngXPad -> SeqEnum`

#### `Roots(f, R): RngUPolXPadElt, RngXPad -> SeqEnum`

#### `Roots(f, R): RngUPolXPadElt, FldXPad -> SeqEnum`

#### `Roots(f): RngUPolXPadElt[FldXPad] -> SeqEnum`

#### `Roots(f): RngUPolXPadElt[RngXPad] -> SeqEnum`

```magma
Max: Infty                    Default: Infinity()
```

Given a polynomial $f$ over an exact $p$-adic ring or field, return the roots of $f$ in the exact $p$-adic field or ring $R$ or the base ring of $f$ if $R$ is not specified. The polynomial $f$ must have no repeated roots (without further assumptions on the structure of the polynomial, no finite-precision $p$-adic algorithm can provably identify a set of equal roots).

#### `HasRoot(f): RngUPolXPadElt[RngXPad] -> BoolElt, RngXPadElt`

#### `HasRoot(f): RngUPolXPadElt[FldXPad] -> BoolElt, FldXPadElt`

#### `HasRoot(f): RngUPolElt[RngXPad] -> BoolElt, RngXPadElt`

#### `HasRoot(f): RngUPolElt[FldXPad] -> BoolElt, FldXPadElt`

#### `HasRoot(f, R): RngUPolElt, FldXPad -> BoolElt, FldXPadElt`

#### `HasRoot(f, R): RngUPolElt, RngXPad -> BoolElt, RngXPadElt`

#### `HasRoot(f, R): RngUPolXPadElt, FldXPad -> BoolElt, FldXPadElt`

#### `HasRoot(f, R): RngUPolXPadElt, RngXPad -> BoolElt, RngXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field, return whether $f$ has a root in the exact $p$-adic ring or field $R$ or the base ring of $f$ if $R$ is not specified. If $f$ does have such a root then also return one root. The polynomial $f$ must have no repeated roots (see [`Roots`](#function-xroots) above).

#### `Factorization(f, R): RngUPolXPadElt, FldXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorisation(f, R): RngUPolXPadElt, FldXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorisation(f, R): RngUPolXPadElt, RngXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorization(f, R): RngUPolXPadElt, RngXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorization(f, R): RngUPolElt, RngXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorisation(f, R): RngUPolElt, RngXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorisation(f, R): RngUPolElt, FldXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorization(f, R): RngUPolElt, FldXPad -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorization(f): RngUPolXPadElt[RngXPad] -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorization(f): RngUPolXPadElt[FldXPad] -> SeqEnum, FldXPadElt, SeqEnum`

#### `Factorisation(f): RngUPolXPadElt[RngXPad] -> SeqEnum, RngXPadElt, SeqEnum`

#### `Factorisation(f): RngUPolXPadElt[FldXPad] -> SeqEnum, FldXPadElt, SeqEnum`

```magma
Certificates : BoolElt                      Default: false
Extensions   : BoolElt                      Default: false
Max          : Infty                        Default: Infinity()
DegreeDivides: RngIntElt                    Default: 0
DegreeGe     : RngIntElt                    Default: 1
```

Given a polynomial $f$ over an exact $p$-adic ring or field, return the factorization of $f$ over $R$ if given or the coefficient ring of $f$ otherwise. The polynomial $f$ must have no repeated factors (for similar reasons to [`Roots`](#function-xroots) above). A scaling factor is also returned, so that the product of the factors equals $f$ multiplied by the scaling factor.

If the parameter `Certificates` is set to `true`, a corresponding sequence of certificates for each factor is also returned. If the parameter `Extensions` is set to `true`, (which implies `Certificates`) then each certificate also includes the extension defined by the factor.

#### `IsIrreducible(f): RngUPolXPadElt[RngXPad] -> BoolElt, Rec`

#### `IsIrreducible(f): RngUPolXPadElt[FldXPad] -> BoolElt, Rec`

#### `IsIrreducible(f): RngUPolElt[RngXPad] -> BoolElt, Rec`

#### `IsIrreducible(f): RngUPolElt[FldXPad] -> BoolElt, Rec`

```magma
Extension  : BoolElt                    Default: false
Certificate: BoolElt                    Default: false
```

Given a polynomial $f$ over an exact $p$-adic ring or field, return whether $f$ is irreducible. It must have at least one non-repeated factor (for similar reasons to [`Roots`](#function-xroots) above). If the parameters `Extension` or `Certificate` are given, the second return value is as in [`Factorization`](#function-xfact).

#### `IsHenselLiftable(f, x): RngUPolElt, FldXPadElt -> BoolElt, FldXPadElt`

#### `IsHenselLiftable(f, x): RngUPolElt, RngXPadElt -> BoolElt, RngXPadElt`

#### `IsHenselLiftable(f, x): RngUPolXPadElt, FldXPadElt -> BoolElt, FldXPadElt`

#### `IsHenselLiftable(f, x): RngUPolXPadElt, RngXPadElt -> BoolElt, RngXPadElt`

Given a polynomial $f$ over an exact $p$-adic ring or field and an element $x$ of an exact $p$-adic ring or field return whether $x$ is close enough to a root of $f$ to be Hensel lifted to that root. If so, returns the lifted root.

#### `RamificationResidualPolynomial(f, face): RngUPolElt[FldXPad], NwtnPgonFace -> RngUPolElt`

#### `RamificationResidualPolynomial(f, face): RngUPolElt[RngXPad], NwtnPgonFace -> RngUPolElt`

#### `RamificationResidualPolynomial(f, face): RngUPolXPadElt[FldXPad], NwtnPgonFace -> RngUPolElt`

#### `RamificationResidualPolynomial(f, face): RngUPolXPadElt[RngXPad], NwtnPgonFace -> RngUPolElt`

Given a polynomial $f$ over an exact $p$-adic ring or field, return the residual polynomial associated to the given $face$ of the ramifcation polygon of $f$.

#### `RamificationResidualPolynomials(f): RngUPolElt[FldXPad] -> SeqEnum, NwtnPgon`

#### `RamificationResidualPolynomials(f): RngUPolElt[RngXPad] -> SeqEnum, NwtnPgon`

#### `RamificationResidualPolynomials(f): RngUPolXPadElt[FldXPad] -> SeqEnum, NwtnPgon`

#### `RamificationResidualPolynomials(f): RngUPolXPadElt[RngXPad] -> SeqEnum, NwtnPgon`

Given an inertial or Eisenstein polynomial $f$ over an exact $p$-adic ring or field, return the residual polynomials assiociated to each face of the ramification polygon of $f$, and the ramification polygon itself.

#### `Example: Fact Ex (ex-95a032)`

```magma
> Qp := pAdicField(17 : Exact);
> P<x> := PolynomialRing(Qp : Exact);
> f := (x - 14)*(x - Qp.1)*(x - Qp.1 - 1);
> NewtonPolygon(f);
Newton Polygon with vertices {(0, 0), (3, 0)} and defining points {(0, 0), (3,
0)}
> HasRoot(f);
true 14 + O(17^20)
> Roots(f);
[ <14 + O(17^20), 1>, <2 + O(17^20), 1>, <1 + O(17^20), 1> ]
> Factorization(f);
[ <(1 + O(17^20))*x - 14 + O(17^20), 1>, <(1 + O(17^20))*x - 2 + O(17^20), 1>,
<(1 + O(17^20))*x - 1 + O(17^20), 1> ]
1 + O(17^20)
> IsIrreducible(f);
false
> IsHenselLiftable(f, Qp!14);
true 14 + O(17^20)
> IsHenselLiftable(f, Qp!10);
false
> RamificationResidualPolynomials(x^3 + 3*17*x^2 + 2*17^2*x + 5*17);
[
    $.1^2 + 3*$.1 + 3
]
Newton Polygon with vertices {(1, 2), (3, 0)} and defining points {(1, 2), (2,
    1), (3, 0)}

```
