This file is indexed.

/usr/share/axiom-20170501/src/algebra/FMONOID.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
)abbrev domain FMONOID FreeMonoid
++ Author: Stephen M. Watt
++ Date Last Updated: 6 June 1991
++ Description:
++ Free monoid on any set of generators
++ The free monoid on a set S is the monoid of finite products of
++ the form \spad{reduce(*,[si ** ni])} where the si's are in S, and the ni's
++ are nonnegative integers. The multiplication is not commutative.

FreeMonoid(S) : SIG == CODE where
  S : SetCategory

  NNI ==> NonNegativeInteger
  REC ==> Record(gen: S, exp: NonNegativeInteger)
  Ex  ==> OutputForm

  SIG ==> Join(Monoid, RetractableTo S) with

        "*" : (S, $) -> $
          ++ s * x returns the product of x by s on the left.

        "*" : ($, S) -> $
          ++ x * s returns the product of x by s on the right.

        "**" : (S, NonNegativeInteger) -> $
          ++ s ** n returns the product of s by itself n times.

        hclf : ($, $) -> $
          ++ hclf(x, y) returns the highest common left factor of x and y,
          ++ the largest d such that \spad{x = d a} and \spad{y = d b}.

        hcrf : ($, $) -> $
          ++ hcrf(x, y) returns the highest common right factor of x and y,
          ++ the largest d such that \spad{x = a d} and \spad{y = b d}.

        lquo : ($, $) -> Union($, "failed")
          ++ lquo(x, y) returns the exact left quotient of x by y 
          ++ q such that \spad{x = y * q},
          ++ "failed" if x is not of the form \spad{y * q}.

        rquo : ($, $) -> Union($, "failed")
          ++ rquo(x, y) returns the exact right quotient of x by y 
          ++ q such that \spad{x = q * y},
          ++ "failed" if x is not of the form \spad{q * y}.

        divide : ($, $) -> Union(Record(lm: $, rm: $), "failed")
          ++ divide(x, y) returns the left and right exact quotients of
          ++ x by y, \spad{[l, r]} such that \spad{x = l * y * r},
          ++ "failed" if x is not of the form \spad{l * y * r}.

        overlap : ($, $) -> Record(lm: $, mm: $, rm: $)
          ++ overlap(x, y) returns \spad{[l, m, r]} such that
          ++ \spad{x = l * m}, \spad{y = m * r} and l and r have no overlap,
          ++ \spad{overlap(l, r) = [l, 1, r]}.

        size : $ -> NNI
          ++ size(x) returns the number of monomials in x.

        factors : $ -> List Record(gen: S, exp: NonNegativeInteger)
          ++ factors(a1\^e1,...,an\^en) returns \spad{[[a1, e1],...,[an, en]]}.

        nthExpon : ($, Integer) -> NonNegativeInteger
          ++ nthExpon(x, n) returns the exponent of the n^th monomial of x.

        nthFactor : ($, Integer) -> S
          ++ nthFactor(x, n) returns the factor of the n^th monomial of x.

        mapExpon : (NNI -> NNI, $) -> $
          ++ mapExpon(f, a1\^e1 ... an\^en) 
          ++ returns \spad{a1\^f(e1) ... an\^f(en)}.

        mapGen : (S -> S, $) -> $
          ++ mapGen(f, a1\^e1 ... an\^en) returns 
          ++\spad{f(a1)\^e1 ... f(an)\^en}.

        if S has OrderedSet then OrderedSet

  CODE ==> ListMonoidOps(S, NonNegativeInteger, 1) add

        Rep := ListMonoidOps(S, NonNegativeInteger, 1)

        1               == makeUnit()

        one? f          == empty? listOfMonoms f

        coerce(f:$): Ex == outputForm(f, "*", "**", 1)

        hcrf(f, g)      == reverse_! hclf(reverse f, reverse g)

        f:$ * s:S       == rightMult(f, s)

        s:S * f:$       == leftMult(s, f)

        factors f       == copy listOfMonoms f

        mapExpon(f, x)  == mapExpon(f, x)$Rep

        mapGen(f, x)    == mapGen(f, x)$Rep

        s:S ** n:NonNegativeInteger == makeTerm(s, n)

        f:$ * g:$ ==
            (f = 1) => g
            (g = 1) => f
            lg := listOfMonoms g
            ls := last(lf := listOfMonoms f)
            ls.gen = lg.first.gen =>
                setlast_!(h := copy lf,[lg.first.gen,lg.first.exp+ls.exp])
                makeMulti concat(h, rest lg)
            makeMulti concat(lf, lg)

        overlap(la, ar) ==
            (la = 1) or (ar = 1) => [la, 1, ar]
            lla := la0 := listOfMonoms la
            lar := listOfMonoms ar
            l:List(REC) := empty()
            while not empty? lla repeat
              if lla.first.gen = lar.first.gen then
                if lla.first.exp < lar.first.exp and empty? rest lla then
                      return [makeMulti l,
                               makeTerm(lla.first.gen, lla.first.exp),
                                 makeMulti concat([lar.first.gen,
                                  (lar.first.exp - lla.first.exp)::NNI],
                                                              rest lar)]
                if lla.first.exp >= lar.first.exp then
                  if (ru:= lquo(makeMulti rest lar,
                    makeMulti rest lla)) case $ then
                      if lla.first.exp > lar.first.exp then
                        l := concat_!(l, [lla.first.gen,
                                  (lla.first.exp - lar.first.exp)::NNI])
                        m := concat([lla.first.gen, lar.first.exp],
                                                               rest lla)
                      else m := lla
                      return [makeMulti l, makeMulti m, ru::$]
              l  := concat_!(l, lla.first)
              lla := rest lla
            [makeMulti la0, 1, makeMulti lar]

        divide(lar, a) ==
            (a = 1) => [lar, 1]
            Na   : Integer := #(la := listOfMonoms a)
            Nlar : Integer := #(llar := listOfMonoms lar)
            l:List(REC) := empty()
            while Na <= Nlar repeat
              if llar.first.gen = la.first.gen and
                 llar.first.exp >= la.first.exp then
                -- Can match a portion of this lar factor.
                -- Now match tail.
                (q:=lquo(makeMulti rest llar,makeMulti rest la))case $ =>
                   if llar.first.exp > la.first.exp then
                       l := concat_!(l, [la.first.gen,
                                  (llar.first.exp - la.first.exp)::NNI])
                   return [makeMulti l, q::$]
              l    := concat_!(l, first llar)
              llar  := rest llar
              Nlar := Nlar - 1
            "failed"

        hclf(f, g) ==
            h:List(REC) := empty()
            for f0 in listOfMonoms f for g0 in listOfMonoms g repeat
                f0.gen ^= g0.gen => return makeMulti h
                h := concat_!(h, [f0.gen, min(f0.exp, g0.exp)])
                f0.exp ^= g0.exp => return makeMulti h
            makeMulti h

        lquo(aq, a) ==
            size a > #(laq := copy listOfMonoms aq) => "failed"
            for a0 in listOfMonoms a repeat
                a0.gen ^= laq.first.gen or a0.exp > laq.first.exp =>
                                                          return "failed"
                if a0.exp = laq.first.exp then laq := rest laq
                else setfirst_!(laq, [laq.first.gen,
                                         (laq.first.exp - a0.exp)::NNI])
            makeMulti laq

        rquo(qa, a) ==
            (u := lquo(reverse qa, reverse a)) case "failed" => "failed"
            reverse_!(u::$)

        if S has OrderedSet then
          a < b ==
            la := listOfMonoms a
            lb := listOfMonoms b
            na: Integer := #la
            nb: Integer := #lb
            while na > 0 and nb > 0 repeat
                la.first.gen > lb.first.gen => return false
                la.first.gen < lb.first.gen => return true
                if la.first.exp = lb.first.exp then
                    la:=rest la
                    lb:=rest lb
                    na:=na - 1
                    nb:=nb - 1
                else if la.first.exp > lb.first.exp then
                    la:=concat([la.first.gen,
                           (la.first.exp - lb.first.exp)::NNI], rest lb)
                    lb:=rest lb
                    nb:=nb - 1
                else
                    lb:=concat([lb.first.gen,
                             (lb.first.exp-la.first.exp)::NNI], rest la)
                    la:=rest la
                    na:=na-1
            empty? la and not empty? lb