<commit_before>################################################################################
#
#  Types
#
################################################################################

mutable struct RelFinField{T} <: FinField
  defining_polynomial::PolyElem{T}
  var::Symbol
  absolute_field::Nemo.FinFieldMorphism
  basis_tr::Vector{T}

  function RelFinField(f::PolyElem{T}, v::Symbol) where T
    K = new{T}()
    K.defining_polynomial = f
    K.var = v
    return K
  end
end

mutable struct RelFinFieldElem{S, T} <: FinFieldElem
  parent::S
  data::T
end

################################################################################
#
#  Show functions
#
################################################################################

function Base.show(io::IO, F::RelFinField)
  print(io, "Field extension defined by $(defining_polynomial(F)) over $(base_field(F)) ")
end

function Base.show(io::IO, a::RelFinFieldElem)
  print(io, AbstractAlgebra.obj_to_string(a, context = io))
end

function AbstractAlgebra.expressify(a::RelFinFieldElem; context = nothing)
  return AbstractAlgebra.expressify(a.data, var(parent(a)),
                                    context = context)
end

############################################################################
#
#  Basic properties
#
############################################################################

var(F::RelFinField) = F.var

prime_field(F::RelFinField; cached::Bool = true) = prime_field(base_field(F), cached = cached)

function defining_polynomial(F::RelFinField{T}) where T 
  return F.defining_polynomial::dense_poly_type(T)
end

base_field(F::RelFinField{S}) where S= base_ring(F.defining_polynomial)::parent_type(S)

characteristic(F::RelFinField) = characteristic(base_field(F))

order(F::RelFinField) = order(base_field(F))^degree(F)

degree(F::RelFinField) = degree(defining_polynomial(F))

################################################################################
#
#  Absolute degree
#
################################################################################

absolute_degree(F::RelFinField) = degree(F)*absolute_degree(base_field(F))
absolute_degree(F::FinField) = degree(F)

################################################################################
#
#  Deepcopy
#
################################################################################

function Base.deepcopy_internal(x::RelFinFieldElem{S, T}, id::IdDict) where {S, T} 
  return RelFinFieldElem{S, T}(x.parent, Base.deepcopy_internal(x.data, id))
end

################################################################################
#
#  Promotion rules
#
################################################################################

AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{S, T}}, ::Type{fmpz}) where {S, T} = RelFinFieldElem{S, T}

AbstractAlgebra.promote_rule(::Type{fmpz}, ::Type{RelFinFieldElem{S, T}}) where {S, T} = RelFinFieldElem{S, T}

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{V}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}} 
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{V}, ::Type{RelFinFieldElem{RelFinField{S}, T}}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}} 
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{S, T}}, ::Type{RelFinFieldElem{S, T}}) where {S, T}
  return RelFinFieldElem{S, T}
end

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{RelFinFieldElem{RelFinField{U}, V}}) where {S <: FinFieldElem, T, U <: FinFieldElem, V}
  if AbstractAlgebra.promote_rule(S, RelFinFieldElem{RelFinField{U}, V}) === S 
    return RelFinFieldElem{RelFinField{S}, T}
  elseif AbstractAlgebra.promote_rule(U, RelFinFieldElem{RelFinField{S}, T}) == U 
    return RelFinFieldElem{RelFinField{U}, V}
  else
    return Union{}
  end
end

################################################################################
#
#  Basic properties of elements
#
################################################################################

parent(a::RelFinFieldElem) = a.parent
data(a::RelFinFieldElem) = a.data

iszero(x::RelFinFieldElem) = iszero(x.data)
isone(x::RelFinFieldElem) = isone(x.data)
isunit(x::RelFinFieldElem) = !iszero(x)

==(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T} = x.data == y.data 

coeff(a::RelFinFieldElem, i::Int) = coeff(a.data, i)
<commit_msg>new attempt<commit_after>################################################################################
#
#  Types
#
################################################################################

mutable struct RelFinField{T} <: FinField
  defining_polynomial::PolyElem{T}
  var::Symbol
  absolute_field::Nemo.FinFieldMorphism
  basis_tr::Vector{T}

  function RelFinField(f::PolyElem{T}, v::Symbol) where T
    K = new{T}()
    K.defining_polynomial = f
    K.var = v
    return K
  end
end

mutable struct RelFinFieldElem{S, T} <: FinFieldElem
  parent::S
  data::T
end

################################################################################
#
#  Show functions
#
################################################################################

function Base.show(io::IO, F::RelFinField)
  print(io, "Field extension defined by $(defining_polynomial(F)) over $(base_field(F)) ")
end

function Base.show(io::IO, a::RelFinFieldElem)
  print(io, AbstractAlgebra.obj_to_string(a, context = io))
end

function AbstractAlgebra.expressify(a::RelFinFieldElem; context = nothing)
  return AbstractAlgebra.expressify(a.data, var(parent(a)),
                                    context = context)
end

############################################################################
#
#  Basic properties
#
############################################################################

var(F::RelFinField) = F.var

prime_field(F::RelFinField; cached::Bool = true) = prime_field(base_field(F), cached = cached)

function defining_polynomial(F::RelFinField{T}) where T 
  return F.defining_polynomial::dense_poly_type(T)
end

base_field(F::RelFinField{S}) where S= base_ring(F.defining_polynomial)::parent_type(S)

characteristic(F::RelFinField) = characteristic(base_field(F))

order(F::RelFinField) = order(base_field(F))^degree(F)

degree(F::RelFinField) = degree(defining_polynomial(F))

################################################################################
#
#  Absolute degree
#
################################################################################

absolute_degree(F::RelFinField) = degree(F)*absolute_degree(base_field(F))
absolute_degree(F::FinField) = degree(F)

################################################################################
#
#  Deepcopy
#
################################################################################

function Base.deepcopy_internal(x::RelFinFieldElem{S, T}, id::IdDict) where {S, T} 
  return RelFinFieldElem{S, T}(x.parent, Base.deepcopy_internal(x.data, id))
end

################################################################################
#
#  Promotion rules
#
################################################################################

AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{S, T}}, ::Type{fmpz}) where {S, T} = RelFinFieldElem{S, T}

AbstractAlgebra.promote_rule(::Type{fmpz}, ::Type{RelFinFieldElem{S, T}}) where {S, T} = RelFinFieldElem{S, T}

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{V}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}} 
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{V}, ::Type{RelFinFieldElem{RelFinField{S}, T}}) where {S, T, V <: Union{fq_nmod, fq, gfp_elem, gfp_fmpz_elem}} 
  U = AbstractAlgebra.promote_rule(S, fq_nmod)
  if U === S
    return RelFinFieldElem{RelFinField{S}, T}
  else
    return Union{}
  end
end

function AbstractAlgebra.promote_rule(::Type{RelFinFieldElem{RelFinField{S}, T}}, ::Type{RelFinFieldElem{RelFinField{U}, V}}) where {S <: FinFieldElem, T, U <: FinFieldElem, V}
  if AbstractAlgebra.promote_rule(S, RelFinFieldElem{RelFinField{U}, V}) === S 
    return RelFinFieldElem{RelFinField{S}, T}
  elseif AbstractAlgebra.promote_rule(U, RelFinFieldElem{RelFinField{S}, T}) == U 
    return RelFinFieldElem{RelFinField{U}, V}
  else
    return Union{}
  end
end

################################################################################
#
#  Basic properties of elements
#
################################################################################

parent(a::RelFinFieldElem) = a.parent
data(a::RelFinFieldElem) = a.data

iszero(x::RelFinFieldElem) = iszero(x.data)
isone(x::RelFinFieldElem) = isone(x.data)
isunit(x::RelFinFieldElem) = !iszero(x)

==(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T} = x.data == y.data 

coeff(a::RelFinFieldElem, i::Int) = coeff(a.data, i)

{'fraction_non_alphanumeric': 0.35314421313774136, 'fraction_numerical': 0.0, 'mean_word_length': 7.763705103969754, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7360935', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2809, 'n_words': 497}