This file is indexed.

/usr/share/axiom-20170501/src/algebra/IAN.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
)abbrev domain IAN InnerAlgebraicNumber
++ Author: Manuel Bronstein
++ Date Created: 22 March 1988
++ Date Last Updated: 4 October 1995 (JHD)
++ Description: 
++ Algebraic closure of the rational numbers.

InnerAlgebraicNumber() : SIG == CODE where

  Z   ==> Integer
  FE  ==> Expression Z
  K   ==> Kernel %
  P   ==> SparseMultivariatePolynomial(Z, K)
  ALGOP ==> "%alg"
  SUP ==>  SparseUnivariatePolynomial

  SIG ==> Join(ExpressionSpace, AlgebraicallyClosedField,
               RetractableTo Z, RetractableTo Fraction Z,
               LinearlyExplicitRingOver Z, RealConstant,
               LinearlyExplicitRingOver Fraction Z,
               CharacteristicZero,
               ConvertibleTo Complex Float, DifferentialRing) with

    coerce : P -> %
      ++ coerce(p) returns p viewed as an algebraic number.

    numer : % -> P
      ++ numer(f) returns the numerator of f viewed as a
      ++ polynomial in the kernels over Z.

    denom : % -> P
      ++ denom(f) returns the denominator of f viewed as a
      ++ polynomial in the kernels over Z.

    reduce : % -> %
      ++ reduce(f) simplifies all the unreduced algebraic numbers
      ++ present in f by applying their defining relations.

    trueEqual : (%,%) -> Boolean
      ++ trueEqual(x,y) tries to determine if the two numbers are equal

    norm : (SUP(%),Kernel %) -> SUP(%)
      ++ norm(p,k) computes the norm of the polynomial p
      ++ with respect to the extension generated by kernel k

    norm : (SUP(%),List Kernel %) -> SUP(%)
      ++ norm(p,l) computes the norm of the polynomial p
      ++ with respect to the extension generated by kernels l

    norm : (%,Kernel %) -> %
      ++ norm(f,k) computes the norm of the algebraic number f
      ++ with respect to the extension generated by kernel k

    norm : (%,List Kernel %) -> %
      ++ norm(f,l) computes the norm of the algebraic number f
      ++ with respect to the extension generated by kernels l

  CODE ==> FE add

    Rep := FE

    -- private
    mainRatDenom(f:%):% ==
       ratDenom(f::Rep::FE)$AlgebraicManipulations(Integer, FE)::Rep::%

    findDenominator(z:SUP %):Record(num:SUP %,den:%) ==
       zz:=z
       while not(zz=0) repeat
          dd:=(denom leadingCoefficient zz)::%
          not(dd=1) =>
             rec:=findDenominator(dd*z)
             return [rec.num,rec.den*dd]
          zz:=reductum zz
       [z,1]

    makeUnivariate(p:P,k:Kernel %):SUP % ==
      map(x+->x::%,univariate(p,k))$SparseUnivariatePolynomialFunctions2(P,%)

    -- public
    a,b:%

    differentiate(x:%):% == 0

    zero? a == zero? numer a

    one? a == (numer a = 1) and (denom a = 1)

    x:% / y:%        == mainRatDenom(x /$Rep y)

    x:% ** n:Integer ==
      n < 0 => mainRatDenom (x **$Rep n)
      x **$Rep n

    trueEqual(a,b) ==
       -- if two algebraic numbers have the same norm (after deleting repeated
       -- roots, then they are certainly conjugates. Note that we start with a
       -- monic polynomial, so don't have to check for constant factors.
       -- this will be fooled by sqrt(2) and -sqrt(2), but the = in
       -- AlgebraicNumber knows what to do about this.
       ka:=reverse tower a
       kb:=reverse tower b
       empty? ka and empty? kb => retract(a)@Fraction Z = retract(b)@Fraction Z
       pa,pb:SparseUnivariatePolynomial %
       pa:=monomial(1,1)-monomial(a,0)
       pb:=monomial(1,1)-monomial(b,0)
       na:=map(retract,norm(pa,ka))_
         $SparseUnivariatePolynomialFunctions2(%,Fraction Z)
       nb:=map(retract,norm(pb,kb))_
         $SparseUnivariatePolynomialFunctions2(%,Fraction Z)
       (sa:=squareFreePart(na)) = (sb:=squareFreePart(nb)) => true
       g:=gcd(sa,sb)
       (dg:=degree g) = 0 => false
       -- of course, if these have a factor in common, then the
       -- answer is really ambiguous, so we ought to be using Duval-type
       -- technology
       dg = degree sa or dg = degree sb => true
       false

    norm(z:%,k:Kernel %): % ==
       p:=minPoly k
       n:=makeUnivariate(numer z,k)
       d:=makeUnivariate(denom z,k)
       resultant(n,p)/resultant(d,p)

    norm(z:%,l:List Kernel %): % ==
       for k in l repeat
           z:=norm(z,k)
       z

    norm(z:SUP %,k:Kernel %):SUP % ==
       p:=map(x +-> x::SUP %,minPoly k)_
         $SparseUnivariatePolynomialFunctions2(%,SUP %)
       f:=findDenominator z
       zz:=map(x +-> makeUnivariate(numer x,k),f.num)_
         $SparseUnivariatePolynomialFunctions2( %,SUP %)
       zz:=swap(zz)$CommuteUnivariatePolynomialCategory(%,SUP %,SUP SUP %)
       resultant(p,zz)/norm(f.den,k)

    norm(z:SUP %,l:List Kernel %): SUP % ==
       for k in l repeat
           z:=norm(z,k)
       z
    belong? op           == belong?(op)$ExpressionSpace_&(%) or has?(op, ALGOP)

    convert(x:%):Float ==
      retract map(y +-> y::Float, x pretend FE)$ExpressionFunctions2(Z,Float)

    convert(x:%):DoubleFloat ==
      retract map(y +-> y::DoubleFloat,x pretend FE)_
        $ExpressionFunctions2(Z, DoubleFloat)

    convert(x:%):Complex(Float) ==
      retract map(y +-> y::Complex(Float),x pretend FE)_
        $ExpressionFunctions2(Z, Complex Float)