Given a polynomial ring `R`

, one wants to be able to define
elements in its fraction field `Q`

.

Here, this is achieved by creating a class `fastfrac`

where an
element in the fraction field is stored as an object `f`

in this
class, with a numerator stored as `f.top`

and a denominator stored
as `f.bot`

(the numerator and denominator are the "top" and
"bottom" of the fraction).

The `__init__`

method of this class `fastfrac`

is built such that:

calling `fastfrac(a, b)`

, with `a`

and `b`

in `R`

,
will return a fraction representing `a/b`

, so it will have
`top`

equal to `a`

and `bot`

equal to `b`

;

this should also work if `a`

is already in `Q`

;
in that case, imagining that `a = c/d`

with `c`

, `d`

in `R`

,
the fraction `f`

equal to `a/b`

should be equal to `(c/d)/b`

,
that is, `c/(d*b)`

;

the implementation is split into two subcases:

if `a`

is in the class fastfrac, this means the `top`

of `a/b`

should be `a.top`

and its `bot`

should be `a.bot * b`

;

otherwise (maybe `a`

belongs to some other implementation
of the fraction field), we access the top and bottom of `a`

by `numerator(a)`

and `denominator(b)`

and then make sure
to transform them into elements of `R`

by doing
`R(numerator(a))`

and `R(denominator(a))`

; so `f`

has
top equal to `R(numerator(a))`

and bottom equal to
`R(denominator(a)) * b`

;

finally, one also wants to be able to call `fastfrac(a)`

instead of `fastfrac(a, 1)`

; so if fastfrac is called with
just one argument (playing the role of `a`

), an extra argument
equal to `1`

(playing the role of `b`

) is inserted.

The if/elif/else clause in the `__init__`

method of the class `fastfrac`

corresponds to the first list item and the two subitems of the second
list item from the explanation.

The first part (the "if") corresponds to `a`

in `ZZ`

or `R`

, where
`ZZ`

is for the case of fractions of type `1/b`

. The "elif" is for
`a`

already in the class `fastfrac`

; the "else" is for `a`

already
in the fraction field but not in the class `fastfrac`

.

Compared to this explanation, `a`

and `b`

are called `top`

and `bot`

in the code, so we have `top.top`

and `top.bot`

instead of `a.top`

and `a.bot`

, and we have `bot`

instead of `b`

.

The presence of the optional argument `bot`

with a default value of `1`

takes care of the last item in the wishlist.

Let us illustrate using polynomials in one variable, for simplicity.

Define

```
sage: R.<x> = PolynomialRing(QQ)
```

and

```
sage: class fastfrac:
....:
....: def __init__(self, top, bot=1):
....:
....: if parent(top) == ZZ or parent(top) == R:
....: self.top = R(top)
....: self.bot = R(bot)
....: elif top.__class__ == fastfrac:
....: self.top = top.top
....: self.bot = top.bot * bot
....: else:
....: self.top = R(numerator(top))
....: self.bot = R(denominator(top)) * bot
....:
```

Then with

```
sage: a = x^2 + 1
sage: b = x^3 - 2
```

one can define their quotient as

```
sage: f = fastfrac(a, b)
```

and recover the "top" and "bottom" of the fraction:

```
sage: f.top
x^2 + 1
sage: f.bot
x^3 - 2
```

By contrast we might have tried to produce the quotient by dividing
`a`

by `b`

:

```
sage: g = a/b
```

and then we can't get the "top" and "bottom" in the same way:

```
sage: g.top
Traceback (most recent call last)
...
AttributeError: 'FractionFieldElement_1poly_field' object has no attribute 'top'
```

This is because the way it was defined, `g`

belongs
to Sage's implementation of the fraction field of `R`

,
and not to the class `fastfrac`

:

```
sage: g.parent()
Fraction Field of Univariate Polynomial Ring in x over Rational Field
```

But nothing to worry about, we can convert `g`

to the class `fastfrac`

easily:

```
sage: h = fastfrac(g)
```

and then we get, as expected:

```
sage: h.top
x^2 + 1
sage: h.bot
x^3 - 2
```

Welcome to Ask Sage! Thank you for your question!

Is this from the file group_prover.sage of the seqp256k1 repository of the bitcoin-core organisation? Or did you come across this code somewhere else?