This file is indexed.

/usr/share/axiom-20170501/src/algebra/FAXF.spad is in axiom-source 20170501-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
)abbrev category FAXF FiniteAlgebraicExtensionField
++ Author: J. Grabmeier, A. Scheerhorn
++ Date Created: 11 March 1991
++ Date Last Updated: 31 March 1991
++ References:
++ Grab92 Finite Fields in Axiom
++ Lidl83 Finite Field, Encyclopedia of Mathematics and Its Applications
++ Description:
++ FiniteAlgebraicExtensionField F is the category of fields
++ which are finite algebraic extensions of the field F.
++ If F is finite then any finite algebraic extension of F 
++ is finite, too. Let K be a finite algebraic extension of the 
++ finite field F. The exponentiation of elements of K 
++ defines a Z-module structure on the multiplicative group of K. 
++ The additive group of K becomes a module over the ring of 
++ polynomials over F via the operation 
++ \spadfun{linearAssociatedExp}(a:K,f:SparseUnivariatePolynomial F)
++ which is linear over F, that is, for elements a from K,
++ c,d from F and f,g univariate polynomials over F
++ we have \spadfun{linearAssociatedExp}(a,cf+dg) equals c times
++ \spadfun{linearAssociatedExp}(a,f) plus d times
++ \spadfun{linearAssociatedExp}(a,g).
++ Therefore \spadfun{linearAssociatedExp} is defined completely by
++ its action on  monomials from F[X]:
++ \spadfun{linearAssociatedExp}(a,monomial(1,k)\$SUP(F)) is defined to be
++ \spadfun{Frobenius}(a,k) which is a**(q**k) where q=size()\$F.
++ The operations order and discreteLog associated with the multiplicative
++ exponentiation have additive analogues associated to the operation
++ \spadfun{linearAssociatedExp}. These are the functions
++ \spadfun{linearAssociatedOrder} and \spadfun{linearAssociatedLog},
++ respectively.

FiniteAlgebraicExtensionField(F) : Category == SIG where
  F : Field

  SIG ==> Join(ExtensionField F, RetractableTo F) with

    -- should be unified with algebras
    -- Join(ExtensionField F, FramedAlgebra F, RetractableTo F) with

    basis : () -> Vector $
      ++ basis() returns a fixed basis of \$ as \spad{F}-vectorspace.

    basis : PositiveInteger -> Vector $
      ++ basis(n) returns a fixed basis of a subfield of \$ as
      ++ \spad{F}-vectorspace.

    coordinates : $ -> Vector F
      ++ coordinates(a) returns the coordinates of \spad{a} with respect
      ++ to the fixed \spad{F}-vectorspace basis.

    coordinates : Vector $ -> Matrix F
      ++ coordinates([v1,...,vm]) returns the coordinates of the
      ++ vi's with to the fixed basis.  The coordinates of vi are
      ++ contained in the ith row of the matrix returned by this
      ++ function.

    represents : Vector F -> $
      ++ represents([a1,..,an]) returns \spad{a1*v1 + ... + an*vn}, where
      ++ v1,...,vn are the elements of the fixed basis.

    minimalPolynomial : $ -> SparseUnivariatePolynomial F
      ++ minimalPolynomial(a) returns the minimal polynomial of an
      ++ element \spad{a} over the ground field F.

    definingPolynomial : () -> SparseUnivariatePolynomial F
      ++ definingPolynomial() returns the polynomial used to define
      ++ the field extension.

    extensionDegree : () ->  PositiveInteger
      ++ extensionDegree() returns the degree of field extension.

    degree : $ -> PositiveInteger
      ++ degree(a) returns the degree of the minimal polynomial of an
      ++ element \spad{a} over the ground field F.

    norm : $  -> F
      ++ norm(a) computes the norm of \spad{a} with respect to the
      ++ field considered as an algebra with 1 over the ground field F.

    trace : $ -> F
      ++ trace(a) computes the trace of \spad{a} with respect to
      ++ the field considered as an algebra with 1 over the ground field F.

    if F has Finite then

      FiniteFieldCategory

      minimalPolynomial : ($,PositiveInteger) -> SparseUnivariatePolynomial $
        ++ minimalPolynomial(x,n) computes the minimal polynomial of x over
        ++ the field of extension degree n over the ground field F.

      norm : ($,PositiveInteger)  -> $
        ++ norm(a,d) computes the norm of \spad{a} with respect to the field
        ++ of extension degree d over the ground field of size.
        ++ Error: if d does not divide the extension degree of \spad{a}.
        ++ Note that norm(a,d) = reduce(*,[a**(q**(d*i)) for i in 0..n/d])

      trace : ($,PositiveInteger)   -> $
        ++ trace(a,d) computes the trace of \spad{a} with respect to the
        ++ field of extension degree d over the ground field of size q.
        ++ Error: if d does not divide the extension degree of \spad{a}.
        ++ Note that 
        ++ \spad{trace(a,d)=reduce(+,[a**(q**(d*i)) for i in 0..n/d])}.

      createNormalElement : () -> $
        ++ createNormalElement() computes a normal element over the ground
        ++ field F, that is,
        ++ \spad{a**(q**i), 0 <= i < extensionDegree()} is an F-basis,
        ++ where \spad{q = size()\$F}.
        ++ Reference: Such an element exists Lidl/Niederreiter: Theorem 2.35.

      normalElement : () -> $
        ++ normalElement() returns a element, normal over the ground field F,
        ++ thus \spad{a**(q**i), 0 <= i < extensionDegree()} is an F-basis,
        ++ where \spad{q = size()\$F}.
        ++ At the first call, the element is computed by
        ++ \spadfunFrom{createNormalElement}{FiniteAlgebraicExtensionField}
        ++ then cached in a global variable.
        ++ On subsequent calls, the element is retrieved by referencing the
        ++ global variable.

      normal? : $ -> Boolean
        ++ normal?(a) tests whether the element \spad{a} is normal over the
        ++ ground field F, that is,
        ++ \spad{a**(q**i), 0 <= i <= extensionDegree()-1} is an F-basis,
        ++ where \spad{q = size()\$F}.
        ++ Implementation according to Lidl/Niederreiter: Theorem 2.39.

      generator : () -> $
        ++ generator() returns a root of the defining polynomial.
        ++ This element generates the field as an algebra over the ground
        ++ field.

      linearAssociatedExp : ($,SparseUnivariatePolynomial F) -> $
        ++ linearAssociatedExp(a,f) is linear over F, that is,
        ++ for elements a from \$, c,d form F and
        ++ f,g univariate polynomials over F we have
        ++ \spadfun{linearAssociatedExp}(a,cf+dg) equals c times
        ++ \spadfun{linearAssociatedExp}(a,f) plus d times
        ++ \spadfun{linearAssociatedExp}(a,g). Therefore
        ++ \spadfun{linearAssociatedExp} is defined completely by its 
        ++ action on monomials from F[X]:
        ++ \spadfun{linearAssociatedExp}(a,monomial(1,k)\$SUP(F)) is 
        ++ defined to be \spadfun{Frobenius}(a,k) which is a**(q**k),
        ++ where q=size()\$F.

      linearAssociatedOrder : $ -> SparseUnivariatePolynomial F
        ++ linearAssociatedOrder(a) retruns the monic polynomial g of
        ++ least degree, such that \spadfun{linearAssociatedExp}(a,g) is 0.

      linearAssociatedLog : $ -> SparseUnivariatePolynomial F
        ++ linearAssociatedLog(a) returns a polynomial g, such that
        ++ \spadfun{linearAssociatedExp}(normalElement(),g) equals a.

      linearAssociatedLog : ($,$) -> _
        Union(SparseUnivariatePolynomial F,"failed")
        ++ linearAssociatedLog(b,a) returns a polynomial g, such 
        ++ that the \spadfun{linearAssociatedExp}(b,g) equals a.
        ++ If there is no such polynomial g, then
        ++ \spadfun{linearAssociatedLog} fails.

   add

    I   ==> Integer
    PI  ==> PositiveInteger
    NNI ==> NonNegativeInteger
    SUP ==> SparseUnivariatePolynomial
    DLP ==> DiscreteLogarithmPackage

    represents(v) ==
      a:$:=0
      b:=basis()
      for i in 1..extensionDegree()@PI repeat
        a:=a+(v.i)*(b.i)
      a

    transcendenceDegree() == 0$NNI

    dimension() == (#basis()) ::NonNegativeInteger::CardinalNumber

    coordinates(v:Vector $) ==
      m := new(#v, extensionDegree(), 0)$Matrix(F)
      for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
        setRow_!(m, j, coordinates qelt(v, i))
      m

    algebraic? a == true

    transcendent? a == false

    extensionDegree() == (#basis()) :: PositiveInteger

    trace a ==
      b := basis()
      abs : F := 0
      for i in 1..#b repeat
        abs := abs + coordinates(a*b.i).i
      abs

    norm a ==
      b := basis()
      m := new(#b,#b, 0)$Matrix(F)
      for i in 1..#b repeat
        setRow_!(m,i, coordinates(a*b.i))
      determinant(m)

    if F has Finite then
      linearAssociatedExp(x,f) ==
        erg:$:=0
        y:=x
        for i in 0..degree(f) repeat
          erg:=erg + coefficient(f,i) * y
          y:=Frobenius(y)
        erg

      linearAssociatedLog(b,x) ==
        x=0 => 0
        l:List List F:=[entries coordinates b]
        a:$:=b
        extdeg:NNI:=extensionDegree()@PI
        for i in 2..extdeg repeat
          a:=Frobenius(a)
          l:=concat(l,entries coordinates a)$(List List F)
        l:=concat(l,entries coordinates x)$(List List F)
        m1:=rowEchelon transpose matrix(l)$(Matrix F)
        v:=zero(extdeg)$(Vector F)
        rown:I:=1
        for i in 1..extdeg repeat
          if qelt(m1,rown,i) = 1$F then
            v.i:=qelt(m1,rown,extdeg+1)
            rown:=rown+1
        p:=+/[monomial(v.(i+1),i::NNI) for i in 0..(#v-1)]
        p=0 =>
         messagePrint("linearAssociatedLog: second argument not in_
                       group generated by first argument")$OutputForm
         "failed"
        p

      linearAssociatedLog(x) == linearAssociatedLog(normalElement(),x) ::
                              SparseUnivariatePolynomial(F)

      linearAssociatedOrder(x) ==
        x=0 => 0
        l:List List F:=[entries coordinates x]
        a:$:=x
        for i in 1..extensionDegree()@PI repeat
          a:=Frobenius(a)
          l:=concat(l,entries coordinates a)$(List List F)
        v:=first nullSpace transpose matrix(l)$(Matrix F)
        +/[monomial(v.(i+1),i::NNI) for i in 0..(#v-1)]

      charthRoot(x):Union($,"failed") ==
        (charthRoot(x)@$)::Union($,"failed")

      minimalPolynomial(a,n) ==
        extensionDegree()@PI rem n ^= 0 =>
          error "minimalPolynomial: 2. argument must divide extension degree"
        f:SUP $:=monomial(1,1)$(SUP $) - monomial(a,0)$(SUP $)
        u:$:=Frobenius(a,n)
        while not(u = a) repeat
          f:=f * (monomial(1,1)$(SUP $) - monomial(u,0)$(SUP $))
          u:=Frobenius(u,n)
        f

      norm(e,s) ==
        qr := divide(extensionDegree(), s)
        zero?(qr.remainder) =>
          pow := (size()-1) quo (size()$F ** s - 1)
          e ** (pow::NonNegativeInteger)
        error "norm: second argument must divide degree of extension"

      trace(e,s) ==
        qr:=divide(extensionDegree(),s)
        q:=size()$F
        zero?(qr.remainder) =>
          a:$:=0
          for i in 0..qr.quotient-1 repeat
            a:=a + e**(q**(s*i))
          a
        error "trace: second argument must divide degree of extension"

      size() == size()$F ** extensionDegree()

      createNormalElement() ==
        characteristic() = size() => 1
        res : $
        for i in 1.. repeat
          res := index(i :: PI)
          not inGroundField? res =>
            normal? res => return res
        -- theorem: there exists a normal element, this theorem is
        -- unknown to the compiler
        res

      normal?(x:$) ==
        p:SUP $:=(monomial(1,extensionDegree()) - monomial(1,0))@(SUP $)
        f:SUP $:= +/[monomial(Frobenius(x,i),i)$(SUP $) _
                   for i in 0..extensionDegree()-1]
        gcd(p,f) = 1 => true
        false

      degree a ==
        y:$:=Frobenius a
        deg:PI:=1
        while y^=a repeat
          y := Frobenius(y)
          deg:=deg+1
        deg