1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//! Small subfields that a kernel can compute inside before lifting its result.
use crate::;
/// A field containing a copy of the small field `S`.
///
/// A kernel whose inputs all lie in `S` can do its arithmetic there and lift only the result.
/// The [`Algebra`] supertrait embeds `S` and lets its elements act on this field.
/// This trait answers whether an element lies in that copy of `S`.
///
/// # Contract
///
/// For every `x: Self`, `s: S` and `values: &[Self]`:
///
/// - `Self::from` is an injective ring homomorphism: it sends `S::ONE` to `Self::ONE`, it
/// commutes with addition and multiplication, and distinct elements of `S` have distinct images.
/// - `x + s`, `x - s` and `x * s` equal `x + Self::from(s)`, `x - Self::from(s)` and
/// `x * Self::from(s)`, and so do the assigning forms.
/// - `x.as_subfield() == Some(s)` holds exactly when `x == Self::from(s)`.
/// So it returns `None` exactly when `x` is the image of no element of `S`.
/// - `Self::all_in_subfield(values)` holds exactly when every `v.as_subfield()` is `Some`.
/// In particular it holds on an empty slice.
///
/// Callers narrow values into `S` on the strength of these equalities, so they must hold exactly.
/// A `Some` for an element outside the subfield would silently compute with a different value.